rtMedia for WordPress, BuddyPress and bbPress - Version 3.10.2

Version Description

Requires BuddyPress 1.7 or higher, if using BuddyPress. Fix XSS vulnerability.

=

Download this release

Release Info

Developer rtcamp
Plugin Icon 128x128 rtMedia for WordPress, BuddyPress and bbPress
Version 3.10.2
Comparing to
See all releases

Code changes from version 3.10.1 to 3.10.2

Files changed (52) hide show
  1. app/assets/admin/img/rtmedia-theme-woffice.jpg +0 -0
  2. app/helper/RTMediaThemes.php +10 -0
  3. app/helper/rtForm.php +1 -1
  4. app/main/controllers/template/rt-template-functions.php +3 -3
  5. index.php +1 -1
  6. lib/freemius/README.md +245 -0
  7. lib/freemius/assets/css/admin/account.css +1 -1
  8. lib/freemius/assets/css/admin/common.css +1 -1
  9. lib/freemius/assets/css/admin/connect.css +1 -1
  10. lib/freemius/assets/scss/admin/account.scss +19 -3
  11. lib/freemius/assets/scss/admin/common.scss +62 -37
  12. lib/freemius/assets/scss/admin/connect.scss +16 -0
  13. lib/freemius/composer.json +10 -0
  14. lib/freemius/config.php +21 -11
  15. lib/freemius/includes/class-freemius-abstract.php +22 -0
  16. lib/freemius/includes/class-freemius.php +461 -352
  17. lib/freemius/includes/class-fs-api.php +169 -69
  18. lib/freemius/includes/class-fs-plugin-updater.php +62 -1
  19. lib/freemius/includes/entities/class-fs-site.php +1 -1
  20. lib/freemius/includes/fs-core-functions.php +2 -152
  21. lib/freemius/includes/fs-essential-functions.php +394 -0
  22. lib/freemius/includes/fs-plugin-functions.php +11 -9
  23. lib/freemius/includes/i18n.php +62 -11
  24. lib/freemius/includes/managers/class-fs-admin-menu-manager.php +7 -2
  25. lib/freemius/includes/managers/class-fs-cache-manager.php +211 -0
  26. lib/freemius/includes/sdk/Exceptions/ArgumentNotExistException.php +4 -0
  27. lib/freemius/includes/sdk/Exceptions/EmptyArgumentException.php +4 -0
  28. lib/freemius/includes/sdk/Exceptions/InvalidArgumentException.php +4 -0
  29. lib/freemius/includes/sdk/Exceptions/OAuthException.php +4 -0
  30. lib/freemius/includes/sdk/Freemius.php +196 -66
  31. lib/freemius/includes/sdk/FreemiusBase.php +13 -52
  32. lib/freemius/start.php +235 -2
  33. lib/freemius/templates/account.php +70 -57
  34. lib/freemius/templates/add-ons.php +7 -3
  35. lib/freemius/templates/admin-notice.php +11 -3
  36. lib/freemius/templates/all-admin-notice.php +4 -0
  37. lib/freemius/templates/checkout.php +4 -0
  38. lib/freemius/templates/connect.php +61 -22
  39. lib/freemius/templates/contact.php +4 -0
  40. lib/freemius/templates/deactivation-feedback-modal.php +10 -5
  41. lib/freemius/templates/debug.php +163 -53
  42. lib/freemius/templates/email.php +4 -0
  43. lib/freemius/templates/firewall-issues-js.php +4 -0
  44. lib/freemius/templates/pending-activation.php +27 -12
  45. lib/freemius/templates/plugin-icon.php +23 -5
  46. lib/freemius/templates/plugin-info/description.php +15 -3
  47. lib/freemius/templates/plugin-info/features.php +18 -2
  48. lib/freemius/templates/plugin-info/screenshots.php +15 -1
  49. lib/freemius/templates/powered-by.php +5 -1
  50. lib/freemius/templates/pricing.php +4 -0
  51. lib/freemius/templates/sticky-admin-notice-js.php +4 -0
  52. readme.txt +9 -5
app/assets/admin/img/rtmedia-theme-woffice.jpg ADDED
Binary file
app/helper/RTMediaThemes.php CHANGED
@@ -205,6 +205,16 @@ class RTMediaThemes {
205
  public function rtmedia_3rd_party_themes_content() {
206
 
207
  $themes = array(
 
 
 
 
 
 
 
 
 
 
208
  'thrive' => array(
209
  'name' => __( 'Thrive - Intranet & Community WordPress Theme', 'buddypress-media' ),
210
  'image' => RTMEDIA_URL . 'app/assets/admin/img/rtmedia-theme-thrive.jpg',
205
  public function rtmedia_3rd_party_themes_content() {
206
 
207
  $themes = array(
208
+ 'woffice' => array(
209
+ 'name' => __( 'Woffice - Intranet/Extranet WordPress Theme', 'buddypress-media' ),
210
+ 'image' => RTMEDIA_URL . 'app/assets/admin/img/rtmedia-theme-woffice.jpg',
211
+ 'demo_url' => 'http://rt.cx/woffice',
212
+ 'author' => __( 'Alkaweb', 'buddypress-media' ),
213
+ 'author_url' => 'http://rt.cx/woffice',
214
+ 'buy_url' => 'http://rt.cx/woffice',
215
+ 'description' => __( 'Woffice is a feature rich, powerful Multipurpose Intranet/Extranet Wordpress theme.', 'buddypress-media' ),
216
+ 'tags' => 'association, community, extranet, intranet, management, network, office, private, projects, school, wiki',
217
+ ),
218
  'thrive' => array(
219
  'name' => __( 'Thrive - Intranet & Community WordPress Theme', 'buddypress-media' ),
220
  'image' => RTMEDIA_URL . 'app/assets/admin/img/rtmedia-theme-thrive.jpg',
app/helper/rtForm.php CHANGED
@@ -415,7 +415,7 @@ if ( ! class_exists( 'rtForm' ) ) {
415
  break;
416
  case 'rtSelect' :
417
  $selected = ( $attrib[ 'selected' ] ) ? 'selected=selected' : '';
418
- $data = '<option value="' . $attrib[ 'value' ] . '" ' . $selected . '>' . $attrib[ 'key' ] . '</option>';
419
  break;
420
  }
421
 
415
  break;
416
  case 'rtSelect' :
417
  $selected = ( $attrib[ 'selected' ] ) ? 'selected=selected' : '';
418
+ $data = '<option value="' . esc_attr( $attrib[ 'value' ] ) . '" ' . $selected . '>' . esc_html( $attrib[ 'key' ] ) . '</option>';
419
  break;
420
  }
421
 
app/main/controllers/template/rt-template-functions.php CHANGED
@@ -1595,7 +1595,7 @@ function rtmedia_global_album_list( $selected_album_id = false ) {
1595
  }
1596
 
1597
  //if ( ( isset ( $rtmedia_query->media_query[ 'album_id' ] ) && ( $album_objects[ 0 ]->id != $rtmedia_query->media_query[ 'album_id' ] ) ) || ! isset ( $rtmedia_query->media_query[ 'album_id' ] ) ){
1598
- $option .= '<option value="' . $album->id . '" ' . $selected . '>' . $album->media_title . '</option>';
1599
  //}
1600
  }
1601
  }
@@ -1625,7 +1625,7 @@ function rtmedia_user_album_list( $get_all = false, $selected_album_id = false )
1625
  }
1626
  if ( $album->context == 'profile' ) {
1627
 
1628
- $profile_option .= '<option value="' . $album->id . '" ' . $selected . '>' . $album->media_title . '</option>';
1629
  }
1630
  // else
1631
  // $option_group .= '<option value="' . $album->id . '">' . $album->media_title . '</option>';
@@ -1667,7 +1667,7 @@ function rtmedia_group_album_list( $selected_album_id = false ) { //by default,
1667
  }
1668
 
1669
  if ( ! in_array( $album->id, $global_albums ) && ( ( isset( $rtmedia_query->media_query[ 'album_id' ] ) && ( $album->id != $rtmedia_query->media_query[ 'album_id' ] ) ) || ! isset( $rtmedia_query->media_query[ 'album_id' ] ) ) ) {
1670
- $option_group .= '<option value="' . $album->id . '" ' . $selected . '>' . $album->media_title . '</option>';
1671
  }
1672
  }
1673
  }
1595
  }
1596
 
1597
  //if ( ( isset ( $rtmedia_query->media_query[ 'album_id' ] ) && ( $album_objects[ 0 ]->id != $rtmedia_query->media_query[ 'album_id' ] ) ) || ! isset ( $rtmedia_query->media_query[ 'album_id' ] ) ){
1598
+ $option .= '<option value="' . $album->id . '" ' . $selected . '>' . esc_html( $album->media_title ) . '</option>';
1599
  //}
1600
  }
1601
  }
1625
  }
1626
  if ( $album->context == 'profile' ) {
1627
 
1628
+ $profile_option .= '<option value="' . $album->id . '" ' . $selected . '>' . esc_html( $album->media_title ) . '</option>';
1629
  }
1630
  // else
1631
  // $option_group .= '<option value="' . $album->id . '">' . $album->media_title . '</option>';
1667
  }
1668
 
1669
  if ( ! in_array( $album->id, $global_albums ) && ( ( isset( $rtmedia_query->media_query[ 'album_id' ] ) && ( $album->id != $rtmedia_query->media_query[ 'album_id' ] ) ) || ! isset( $rtmedia_query->media_query[ 'album_id' ] ) ) ) {
1670
+ $option_group .= '<option value="' . $album->id . '" ' . $selected . '>' . esc_html( $album->media_title ) . '</option>';
1671
  }
1672
  }
1673
  }
index.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: rtMedia for WordPress, BuddyPress and bbPress
5
  Plugin URI: http://rtcamp.com/rtmedia/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
6
  Description: This plugin adds missing media rich features like photos, videos and audio uploading to BuddyPress which are essential if you are building social network, seriously!
7
- Version: 3.10.1
8
  Author: rtCamp
9
  Text Domain: buddypress-media
10
  Author URI: http://rtcamp.com/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
4
  Plugin Name: rtMedia for WordPress, BuddyPress and bbPress
5
  Plugin URI: http://rtcamp.com/rtmedia/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
6
  Description: This plugin adds missing media rich features like photos, videos and audio uploading to BuddyPress which are essential if you are building social network, seriously!
7
+ Version: 3.10.2
8
  Author: rtCamp
9
  Text Domain: buddypress-media
10
  Author URI: http://rtcamp.com/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media
lib/freemius/README.md ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Freemius WordPress SDK
2
+ ======================
3
+
4
+ Freemius is an [analytics](https://freemius.com/wordpress/insights/) & [monetization](https://freemius.com/wordpress/) platform for plugin developers. Freemius empower developers with advanced real-time analytics and helps turning any plugin into a commercial product in less than 10 min.
5
+
6
+ The platform is fully functional and running in production. Having said that, the monetization platform is still in closed beta.
7
+ If you are a WordPress plugin developer and you are interested to monetize with Freemius [apply to our closed beta here](http://bit.ly/freemius-beta):
8
+
9
+ http://bit.ly/freemius-beta
10
+
11
+ **Below you'll find the integration instructions for our WordPress SDK.**
12
+
13
+ ## Initializing the SDK
14
+
15
+ Copy the code below and paste it into the top of your main plugin's PHP file, right after the plugin's header comment:
16
+
17
+ ```php
18
+ <?php
19
+ // Create a helper function for easy SDK access.
20
+ function my_prefix_fs() {
21
+ global $my_prefix_fs;
22
+ if ( ! isset( $my_prefix_fs ) ) {
23
+ // Include Freemius SDK.
24
+ require_once dirname(__FILE__) . '/freemius/start.php';
25
+
26
+ $my_prefix_fs = fs_dynamic_init( array(
27
+ 'id' => '1234',
28
+ 'slug' => 'my-plugin-slug',
29
+ 'menu_slug' => 'my_menu_slug', // You can also use __FILE__
30
+ 'public_key' => 'pk_MY_PUBLIC_KEY',
31
+ 'is_live' => true,
32
+ 'is_premium' => true,
33
+ 'has_addons' => false,
34
+ 'has_paid_plans' => false,
35
+ // Set the SDK to work in a sandbox mode (for development & testing).
36
+ // IMPORTANT: MAKE SURE TO REMOVE SECRET KEY BEFORE DEPLOYMENT.
37
+ 'secret_key' => 'sk_MY_SECRET_KEY',
38
+ ) );
39
+ }
40
+
41
+ return $my_prefix_fs;
42
+ }
43
+
44
+ // Init Freemius.
45
+ my_prefix_fs();
46
+ ?>
47
+ ```
48
+
49
+ - **1234** - Replace with your plugin's ID.
50
+ - **pk_MY_PUBLIC_KEY** - Replace with your plugin's public key.
51
+ - **sk_MY_SECRET_KEY** - Replace with your plugin's secret key.
52
+ - **my-plugin-slug** - Replace with your plugin's WordPress.org slug.
53
+ - **my_menu_slug** - Replace with your admin dashboard settings menu slug.
54
+
55
+
56
+ ## Usage example
57
+
58
+ You can call the SDK by using the shortcode function:
59
+
60
+ ```php
61
+ <?php my_prefix_fs()->get_upgrade_url(); ?>
62
+ ```
63
+
64
+ Or when calling Freemius multiple times in a scope, it's recommended to use it with the global variable:
65
+
66
+ ```php
67
+ <?php
68
+ global $my_prefix_fs;
69
+ $my_prefix_fs->get_account_url();
70
+ ?>
71
+ ```
72
+
73
+ ## Adding license based logic examples
74
+
75
+ Add marketing content to encourage your users to upgrade for your paid version:
76
+
77
+ ```php
78
+ <?php
79
+ if ( my_prefix_fs()->is_not_paying() ) {
80
+ echo '<section><h1>' . __('Awesome Premium Features', 'my-plugin-slug') . '</h1>';
81
+ echo '<a href="' . my_prefix_fs()->get_upgrade_url() . '">' .
82
+ __('Upgrade Now!', 'my-plugin-slug') .
83
+ '</a>';
84
+ echo '</section>';
85
+ }
86
+ ?>
87
+ ```
88
+
89
+ Add logic which will only be available in your premium plugin version:
90
+
91
+ ```php
92
+ <?php
93
+ // This "if" block will be auto removed from the Free version.
94
+ if ( my_prefix_fs()->is__premium_only() ) {
95
+
96
+ // ... premium only logic ...
97
+
98
+ }
99
+ ?>
100
+ ```
101
+
102
+ To add a function which will only be available in your premium plugin version, simply add __premium_only as the suffix of the function name. Just make sure that all lines that call that method directly or by hooks, are also wrapped in premium only logic:
103
+
104
+ ```php
105
+ <?php
106
+ class My_Plugin {
107
+ function init() {
108
+ ...
109
+
110
+ // This "if" block will be auto removed from the free version.
111
+ if ( my_prefix_fs()->is__premium_only() ) {
112
+ // Init premium version.
113
+ $this->admin_init__premium_only();
114
+
115
+ add_action( 'admin_init', array( &$this, 'admin_init_hook__premium_only' );
116
+ }
117
+
118
+ ...
119
+ }
120
+
121
+ // This method will be only included in the premium version.
122
+ function admin_init__premium_only() {
123
+ ...
124
+ }
125
+
126
+ // This method will be only included in the premium version.
127
+ function admin_init_hook__premium_only() {
128
+ ...
129
+ }
130
+ }
131
+ ?>
132
+ ```
133
+
134
+ Add logic which will only be executed for customers in your 'professional' plan:
135
+
136
+ ```php
137
+ <?php
138
+ if ( my_prefix_fs()->is_plan('professional', true) ) {
139
+ // .. logic related to Professional plan only ...
140
+ }
141
+ ?>
142
+ ```
143
+
144
+ Add logic which will only be executed for customers in your 'professional' plan or higher plans:
145
+
146
+ ```php
147
+ <?php
148
+ if ( my_prefix_fs()->is_plan('professional') ) {
149
+ // ... logic related to Professional plan and higher plans ...
150
+ }
151
+ ?>
152
+ ```
153
+
154
+ Add logic which will only be available in your premium plugin version AND will only be executed for customers in your 'professional' plan (and higher plans):
155
+
156
+ ```php
157
+ <?php
158
+ // This "if" block will be auto removed from the Free version.
159
+ if ( my_prefix_fs()->is_plan__premium_only('professional') ) {
160
+ // ... logic related to Professional plan and higher plans ...
161
+ }
162
+ ?>
163
+ ```
164
+
165
+ Add logic only for users in trial:
166
+
167
+ ```php
168
+ <?php
169
+ if ( my_prefix_fs()->is_trial() ) {
170
+ // ... logic for users in trial ...
171
+ }
172
+ ?>
173
+ ```
174
+
175
+ Add logic for specified paid plan:
176
+
177
+ ```php
178
+ <?php
179
+ // This "if" block will be auto removed from the Free version.
180
+ if ( my_prefix_fs()->is__premium_only() ) {
181
+ if ( my_prefix_fs()->is_plan( 'professional', true ) ) {
182
+
183
+ // ... logic related to Professional plan only ...
184
+
185
+ } else if ( my_prefix_fs()->is_plan( 'business' ) ) {
186
+
187
+ // ... logic related to Business plan and higher plans ...
188
+
189
+ }
190
+ }
191
+ ?>
192
+ ```
193
+
194
+ ## Excluding files and folders from the free plugin version
195
+ There are two ways to exclude files from your free version.
196
+
197
+ 1. Add `__premium_only` just before the file extension. For example, functions__premium_only.php will be only included in the premium plugin version. This works for all type of files, not only PHP.
198
+ 2. Add `@fs_premium_only` a sepcial meta tag to the plugin's main PHP file header. Example:
199
+ ```php
200
+ <?php
201
+ /**
202
+ * Plugin Name: My Very Awesome Plugin
203
+ * Plugin URI: http://my-awesome-plugin.com
204
+ * Description: Create and manage Awesomeness right in WordPress.
205
+ * Version: 1.0.0
206
+ * Author: Awesomattic
207
+ * Author URI: http://my-awesome-plugin.com/me/
208
+ * License: GPLv2
209
+ * Text Domain: myplugin
210
+ * Domain Path: /langs
211
+ *
212
+ * @fs_premium_only /lib/functions.php, /premium-files/
213
+ */
214
+
215
+ if ( ! defined( 'ABSPATH' ) ) {
216
+ exit;
217
+ }
218
+
219
+ // ... my code ...
220
+ ?>
221
+ ```
222
+ The file `/lib/functions.php` and the directory `/premium-files/` will be removed from the free plugin version.
223
+
224
+ # WordPress.org Compliance
225
+ Based on [WordPress.org Guidelines](https://wordpress.org/plugins/about/guidelines/) you are not allowed to submit a plugin that has premium code in it:
226
+ > All code hosted by WordPress.org servers must be free and fully-functional. If you want to sell advanced features for a plugin (such as a "pro" version), then you must sell and serve that code from your own site, we will not host it on our servers.
227
+
228
+ Therefore, if you want to deploy your free plugin's version to WordPress.org, make sure you wrap all your premium code with `if ( my_prefix_fs()->{{ method }}__premium_only() )` or the other methods provided to exclude premium features & files from the free version.
229
+
230
+ ## Deployment
231
+ Zip your plugin's root folder and upload it in the Deployment section in the *Freemius Developer's Dashboard*.
232
+ The plugin will be scanned and processed by a custom developed *PHP Processor* which will auto-generate two versions of your plugin:
233
+
234
+ 1. **Premium version**: Identical to your uploaded version, including all code (except your `secret_key`). Will be enabled for download ONLY for your paying or in trial customers.
235
+ 2. **Free version**: The code stripped from all your paid features (based on the logic added wrapped in `{ method }__premium_only()`).
236
+
237
+ The free version is the one that you should give your users to download. Therefore, download the free generated version and upload to your site. Or, if your plugin was WordPress.org complaint and you made sure to exclude all your premium code with the different provided techniques, you can deploy the downloaded free version to the .org repo.
238
+
239
+ ## Reporting Bugs
240
+ Email dev [at] freemius [dot] com
241
+
242
+ ## FAQ
243
+
244
+ ## Copyright
245
+ Freemius, Inc.
lib/freemius/assets/css/admin/account.css CHANGED
@@ -1 +1 @@
1
- #fs_account .postbox,#fs_account .widefat{max-width:700px}#fs_account .fs-header-actions{position:absolute;top:10px;right:10px;font-size:0.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}.rtl #fs_account .fs-header-actions{left:10px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table td label{background:orange;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table var,.fs-key-value-table code{color:#0073AA;font-size:16px;background:none}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}
1
+ #fs_account .postbox,#fs_account .widefat{max-width:700px}#fs_account h3{font-size:1.3em;padding:12px 12px 12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #F1F1F1}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:0.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table td label{background:orange;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table var,.fs-key-value-table code{color:#0073AA;font-size:16px;background:none}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}
lib/freemius/assets/css/admin/common.css CHANGED
@@ -1 +1 @@
1
- .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-close{position:absolute;top:10px;right:10px;cursor:pointer;color:#ccc}.fs-notice .fs-close:hover{color:#aaa}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;bottom:-22px;top:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}.rtl .fs-notice .fs-close{left:10px;right:auto}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;box-shadow:0px 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}
1
+ .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;bottom:-22px;top:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;box-shadow:0px 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}
lib/freemius/assets/css/admin/connect.css CHANGED
@@ -1 +1 @@
1
- #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li div{margin-left:55px}#fs_connect .fs-permissions ul li div span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li div p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li div{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
1
+ #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li div{margin-left:55px}#fs_connect .fs-permissions ul li div span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li div p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li div{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
lib/freemius/assets/scss/admin/account.scss CHANGED
@@ -6,11 +6,27 @@
6
  max-width: 700px;
7
  }
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  .fs-header-actions
10
  {
11
  position: absolute;
12
- top: 10px;
13
- right: 10px;
14
  font-size: 0.9em;
15
 
16
  ul
@@ -36,7 +52,7 @@
36
 
37
  .rtl #fs_account .fs-header-actions
38
  {
39
- left: 10px;
40
  right: auto;
41
  }
42
 
6
  max-width: 700px;
7
  }
8
 
9
+ h3
10
+ {
11
+ font-size: 1.3em;
12
+ padding: 12px 12px 12px 15px;
13
+ margin: 0 0 12px 0;
14
+ line-height: 1.4;
15
+ border-bottom: 1px solid #F1F1F1;
16
+ }
17
+
18
+ i.dashicons
19
+ {
20
+ font-size: 1.2em;
21
+ height: 1.2em;
22
+ width: 1.2em;
23
+ }
24
+
25
  .fs-header-actions
26
  {
27
  position: absolute;
28
+ top: 17px;
29
+ right: 15px;
30
  font-size: 0.9em;
31
 
32
  ul
52
 
53
  .rtl #fs_account .fs-header-actions
54
  {
55
+ left: 15px;
56
  right: auto;
57
  }
58
 
lib/freemius/assets/scss/admin/common.scss CHANGED
@@ -11,63 +11,87 @@
11
 
12
  &.success
13
  {
14
- color: green;
15
- // font-weight: normal;
16
  }
17
 
18
  &.promotion
19
  {
20
- border-color: $fs-notice-promotion-border-color !important;
21
  background-color: $fs-notice-promotion-bkg !important;
22
  }
23
 
 
 
 
 
 
 
24
  .fs-close
25
  {
26
- position: absolute;
27
- top: 10px;
28
- right: 10px;
 
 
 
 
29
  cursor: pointer;
30
- color: #ccc;
 
31
 
32
  &:hover
33
  {
34
- color: #aaa;
 
 
 
 
 
 
 
35
  }
36
  }
37
 
38
  label.fs-plugin-title
39
  {
40
- background: rgba(0, 0, 0, 0.3);
41
- color: #fff;
42
- padding: 2px 10px;
43
- position: absolute;
44
- bottom: -22px;
45
- top: auto;
46
- right: auto;
47
  @include border-radius(0 0 3px 3px);
48
- left: 10px;
49
- font-size: 12px;
50
  font-weight: bold;
51
- cursor: auto;
52
  }
53
  }
54
 
55
- .rtl .fs-notice .fs-close
56
  {
57
- left: 10px;
58
- right: auto;
 
 
 
 
 
 
59
  }
60
 
61
  .fs-secure-notice
62
  {
63
- position: fixed;
64
- top: 32px;
65
- left: 160px;
66
- right: 0;
67
  background: rgb(235, 253, 235);
68
- padding: 10px 20px;
69
- color: green;
70
- z-index: 9999;
71
  box-shadow: 0px 2px 2px rgba(6, 113, 6, 0.3);
72
  @include opacity(0.95);
73
 
@@ -77,32 +101,33 @@
77
  }
78
  }
79
 
80
- @media screen and (max-width: 960px)
81
- {
82
  .fs-secure-notice
83
  {
84
  left: 36px;
85
  }
86
  }
87
 
88
- @media screen and (max-width: 782px)
89
- {
90
  .fs-secure-notice
91
  {
92
- left: 0;
93
- top: 46px;
94
  text-align: center;
95
  }
96
  }
97
 
98
- span.fs-submenu-item.fs-sub:before {
 
99
  // Add small arrow.
100
  content: '\21B3';
101
  padding: 0 5px;
102
  }
103
 
104
- .rtl {
105
- span.fs-submenu-item.fs-sub:before {
 
 
106
  // Add small RTL arrow.
107
  content: '\21B2';
108
  }
11
 
12
  &.success
13
  {
14
+ color: green;
15
+ // font-weight: normal;
16
  }
17
 
18
  &.promotion
19
  {
20
+ border-color: $fs-notice-promotion-border-color !important;
21
  background-color: $fs-notice-promotion-bkg !important;
22
  }
23
 
24
+ .fs-notice-body
25
+ {
26
+ margin: .5em 0;
27
+ padding: 2px;
28
+ }
29
+
30
  .fs-close
31
  {
32
+ // position: absolute;
33
+ // top: 2px;
34
+ // bottom: 2px;
35
+ // right: 2px;
36
+ // min-width: 100px;
37
+ // text-align: center;
38
+ // padding-right: 2px;
39
  cursor: pointer;
40
+ color: #aaa;
41
+ float: right;
42
 
43
  &:hover
44
  {
45
+ color: #666;
46
+ // background: #A9A9A9;
47
+ }
48
+
49
+ > *
50
+ {
51
+ margin-top: 7px;
52
+ display: inline-block;
53
  }
54
  }
55
 
56
  label.fs-plugin-title
57
  {
58
+ background: rgba(0, 0, 0, 0.3);
59
+ color: #fff;
60
+ padding: 2px 10px;
61
+ position: absolute;
62
+ bottom: -22px;
63
+ top: auto;
64
+ right: auto;
65
  @include border-radius(0 0 3px 3px);
66
+ left: 10px;
67
+ font-size: 12px;
68
  font-weight: bold;
69
+ cursor: auto;
70
  }
71
  }
72
 
73
+ .rtl .fs-notice
74
  {
75
+ .fs-close
76
+ {
77
+ // left: 2px;
78
+ // right: auto;
79
+ // padding-right: 0;
80
+ // padding-left: 2px;
81
+ float: left;
82
+ }
83
  }
84
 
85
  .fs-secure-notice
86
  {
87
+ position: fixed;
88
+ top: 32px;
89
+ left: 160px;
90
+ right: 0;
91
  background: rgb(235, 253, 235);
92
+ padding: 10px 20px;
93
+ color: green;
94
+ z-index: 9999;
95
  box-shadow: 0px 2px 2px rgba(6, 113, 6, 0.3);
96
  @include opacity(0.95);
97
 
101
  }
102
  }
103
 
104
+ @media screen and (max-width: 960px) {
 
105
  .fs-secure-notice
106
  {
107
  left: 36px;
108
  }
109
  }
110
 
111
+ @media screen and (max-width: 782px) {
 
112
  .fs-secure-notice
113
  {
114
+ left: 0;
115
+ top: 46px;
116
  text-align: center;
117
  }
118
  }
119
 
120
+ span.fs-submenu-item.fs-sub:before
121
+ {
122
  // Add small arrow.
123
  content: '\21B3';
124
  padding: 0 5px;
125
  }
126
 
127
+ .rtl
128
+ {
129
+ span.fs-submenu-item.fs-sub:before
130
+ {
131
  // Add small RTL arrow.
132
  content: '\21B2';
133
  }
lib/freemius/assets/scss/admin/connect.scss CHANGED
@@ -56,6 +56,14 @@ $form_width: 480px;
56
  {
57
  content: ' \279C';
58
  }
 
 
 
 
 
 
 
 
59
  }
60
 
61
  &.button-secondary
@@ -292,6 +300,14 @@ $form_width: 480px;
292
  {
293
  content: ' \000bb';
294
  }
 
 
 
 
 
 
 
 
295
  }
296
 
297
  &.button-secondary
56
  {
57
  content: ' \279C';
58
  }
59
+
60
+ &.fs-loading
61
+ {
62
+ &:after
63
+ {
64
+ content: '';
65
+ }
66
+ }
67
  }
68
 
69
  &.button-secondary
300
  {
301
  content: ' \000bb';
302
  }
303
+
304
+ &.fs-loading
305
+ {
306
+ &:after
307
+ {
308
+ content: '';
309
+ }
310
+ }
311
  }
312
 
313
  &.button-secondary
lib/freemius/composer.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "freemius/wordpress-sdk",
3
+ "description": "Freemius WordPress SDK",
4
+ "keywords": ["freemius", "wordpress", "plugin", "sdk"],
5
+ "homepage": "https://freemius.com",
6
+ "license": "GPL-2.0+",
7
+ "require": {
8
+ "php": ">=5.2"
9
+ }
10
+ }
lib/freemius/config.php CHANGED
@@ -39,7 +39,7 @@
39
  */
40
  if ( ! defined( 'WP_FS__LOCALHOST_IP' ) ) {
41
  // VVV default public network IP.
42
- define( 'WP_FS__VVV_DEFAULT_PUBLIC_IP', '192.168.50.1' );
43
 
44
  // define( 'WP_FS__LOCALHOST_IP', WP_FS__VVV_DEFAULT_PUBLIC_IP );
45
  }
@@ -56,8 +56,9 @@
56
  * THEREFORE, MAKE SURE THAT WHEN USING THIS PARAMETER,YOUR TESTING ENVIRONMENT'S
57
  * CLOCK IS SYNCED.
58
  */
59
- define( 'WP_FS__SKIP_EMAIL_ACTIVATION', false );
60
-
 
61
 
62
  /**
63
  * Directories
@@ -81,17 +82,25 @@
81
  define( 'WP_FS__ADDRESS_LOCALHOST', 'http://' . WP_FS__DOMAIN_LOCALHOST . ':8080' );
82
  define( 'WP_FS__ADDRESS_PRODUCTION', 'https://' . WP_FS__DOMAIN_PRODUCTION );
83
 
 
 
 
84
  define( 'WP_FS__IS_PRODUCTION_MODE', ! defined( 'WP_FS__DEV_MODE' ) || ! WP_FS__DEV_MODE || ( WP_FS__TESTING_DOMAIN !== $_SERVER['HTTP_HOST'] ) );
85
 
86
  define( 'WP_FS__ADDRESS', ( WP_FS__IS_PRODUCTION_MODE ? WP_FS__ADDRESS_PRODUCTION : WP_FS__ADDRESS_LOCALHOST ) );
87
 
88
  if ( defined( 'WP_FS__LOCALHOST_IP' ) ) {
89
- define( 'WP_FS__IS_LOCALHOST', ( WP_FS__LOCALHOST_IP == $_SERVER['REMOTE_ADDR'] ) );
90
  } else {
91
- define( 'WP_FS__IS_LOCALHOST', ( substr( $_SERVER['REMOTE_ADDR'], 0, 4 ) == '127.' || $_SERVER['REMOTE_ADDR'] == '::1' ) );
 
 
 
 
92
  }
93
 
94
- define( 'WP_FS__IS_LOCALHOST_FOR_SERVER', ( false !== strpos( $_SERVER['HTTP_HOST'], 'localhost' ) ) );
 
95
 
96
  // Set API address for local testing.
97
  if ( ! WP_FS__IS_PRODUCTION_MODE ) {
@@ -109,7 +118,7 @@
109
  }
110
  define( 'WP_FS__OPTIONS_OPTION_NAME', WP_FS___OPTION_PREFIX . 'options' );
111
 
112
- define( 'WP_FS__IS_HTTPS', (
113
  // Checks if CloudFlare's HTTPS (Flexible SSL support)
114
  isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === strtolower( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) ||
115
  // Check if HTTPS request.
@@ -117,7 +126,8 @@
117
  ( isset( $_SERVER['SERVER_PORT'] ) && 443 == $_SERVER['SERVER_PORT'] )
118
  );
119
 
120
- define( 'WP_FS__IS_POST_REQUEST', ( strtoupper( $_SERVER['REQUEST_METHOD'] ) == 'POST' ) );
 
121
 
122
  /**
123
  * Billing Frequencies
@@ -136,7 +146,7 @@
136
  /**
137
  * Times in seconds
138
  */
139
- // define( 'WP_FS__TIME_5_MIN_IN_SEC', 300 );
140
  define( 'WP_FS__TIME_10_MIN_IN_SEC', 600 );
141
  // define( 'WP_FS__TIME_15_MIN_IN_SEC', 900 );
142
  define( 'WP_FS__TIME_24_HOURS_IN_SEC', 86400 );
@@ -144,8 +154,8 @@
144
  /**
145
  * Debugging
146
  */
147
- define( 'WP_FS__DEBUG_SDK', ! empty( $_GET['fs_dbg'] ) );
148
- define( 'WP_FS__ECHO_DEBUG_SDK', ! empty( $_GET['fs_dbg_echo'] ) );
149
  define( 'WP_FS__LOG_DATETIME_FORMAT', 'Y-n-d H:i:s' );
150
 
151
  if ( WP_FS__ECHO_DEBUG_SDK ) {
39
  */
40
  if ( ! defined( 'WP_FS__LOCALHOST_IP' ) ) {
41
  // VVV default public network IP.
42
+ define( 'WP_FS__VVV_DEFAULT_PUBLIC_IP', '192.168.50.4' );
43
 
44
  // define( 'WP_FS__LOCALHOST_IP', WP_FS__VVV_DEFAULT_PUBLIC_IP );
45
  }
56
  * THEREFORE, MAKE SURE THAT WHEN USING THIS PARAMETER,YOUR TESTING ENVIRONMENT'S
57
  * CLOCK IS SYNCED.
58
  */
59
+ if ( ! defined( 'WP_FS__SKIP_EMAIL_ACTIVATION' ) ) {
60
+ define( 'WP_FS__SKIP_EMAIL_ACTIVATION', false );
61
+ }
62
 
63
  /**
64
  * Directories
82
  define( 'WP_FS__ADDRESS_LOCALHOST', 'http://' . WP_FS__DOMAIN_LOCALHOST . ':8080' );
83
  define( 'WP_FS__ADDRESS_PRODUCTION', 'https://' . WP_FS__DOMAIN_PRODUCTION );
84
 
85
+ define( 'WP_FS__IS_HTTP_REQUEST', isset( $_SERVER['HTTP_HOST'] ) );
86
+ define( 'WP_FS__REMOTE_ADDR', fs_get_ip() );
87
+
88
  define( 'WP_FS__IS_PRODUCTION_MODE', ! defined( 'WP_FS__DEV_MODE' ) || ! WP_FS__DEV_MODE || ( WP_FS__TESTING_DOMAIN !== $_SERVER['HTTP_HOST'] ) );
89
 
90
  define( 'WP_FS__ADDRESS', ( WP_FS__IS_PRODUCTION_MODE ? WP_FS__ADDRESS_PRODUCTION : WP_FS__ADDRESS_LOCALHOST ) );
91
 
92
  if ( defined( 'WP_FS__LOCALHOST_IP' ) ) {
93
+ define( 'WP_FS__IS_LOCALHOST', ( WP_FS__LOCALHOST_IP === WP_FS__REMOTE_ADDR ) );
94
  } else {
95
+ define( 'WP_FS__IS_LOCALHOST', WP_FS__IS_HTTP_REQUEST &&
96
+ is_string( WP_FS__REMOTE_ADDR ) &&
97
+ ( substr( WP_FS__REMOTE_ADDR, 0, 4 ) == '127.' ||
98
+ WP_FS__REMOTE_ADDR == '::1' )
99
+ );
100
  }
101
 
102
+ define( 'WP_FS__IS_LOCALHOST_FOR_SERVER', ( ! WP_FS__IS_HTTP_REQUEST ||
103
+ false !== strpos( $_SERVER['HTTP_HOST'], 'localhost' ) ) );
104
 
105
  // Set API address for local testing.
106
  if ( ! WP_FS__IS_PRODUCTION_MODE ) {
118
  }
119
  define( 'WP_FS__OPTIONS_OPTION_NAME', WP_FS___OPTION_PREFIX . 'options' );
120
 
121
+ define( 'WP_FS__IS_HTTPS', ( WP_FS__IS_HTTP_REQUEST &&
122
  // Checks if CloudFlare's HTTPS (Flexible SSL support)
123
  isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === strtolower( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) ||
124
  // Check if HTTPS request.
126
  ( isset( $_SERVER['SERVER_PORT'] ) && 443 == $_SERVER['SERVER_PORT'] )
127
  );
128
 
129
+ define( 'WP_FS__IS_POST_REQUEST', ( WP_FS__IS_HTTP_REQUEST &&
130
+ strtoupper( $_SERVER['REQUEST_METHOD'] ) == 'POST' ) );
131
 
132
  /**
133
  * Billing Frequencies
146
  /**
147
  * Times in seconds
148
  */
149
+ define( 'WP_FS__TIME_5_MIN_IN_SEC', 300 );
150
  define( 'WP_FS__TIME_10_MIN_IN_SEC', 600 );
151
  // define( 'WP_FS__TIME_15_MIN_IN_SEC', 900 );
152
  define( 'WP_FS__TIME_24_HOURS_IN_SEC', 86400 );
154
  /**
155
  * Debugging
156
  */
157
+ define( 'WP_FS__DEBUG_SDK', WP_FS__DEV_MODE && ! empty( $_GET['fs_dbg'] ) );
158
+ define( 'WP_FS__ECHO_DEBUG_SDK', WP_FS__DEV_MODE && ! empty( $_GET['fs_dbg_echo'] ) );
159
  define( 'WP_FS__LOG_DATETIME_FORMAT', 'Y-n-d H:i:s' );
160
 
161
  if ( WP_FS__ECHO_DEBUG_SDK ) {
lib/freemius/includes/class-freemius-abstract.php CHANGED
@@ -336,6 +336,28 @@
336
  */
337
  abstract function get_upgrade_url( $period = WP_FS__PERIOD_ANNUALLY );
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  #region Marketing ------------------------------------------------------------------
340
 
341
  /**
336
  */
337
  abstract function get_upgrade_url( $period = WP_FS__PERIOD_ANNUALLY );
338
 
339
+ /**
340
+ * Check if Freemius was first added in a plugin update.
341
+ *
342
+ * @author Vova Feldman (@svovaf)
343
+ * @since 1.1.5
344
+ *
345
+ * @return bool
346
+ */
347
+ function is_plugin_update() {
348
+ return ! $this->is_plugin_new_install();
349
+ }
350
+
351
+ /**
352
+ * Check if Freemius was part of the plugin when the user installed it first.
353
+ *
354
+ * @author Vova Feldman (@svovaf)
355
+ * @since 1.1.5
356
+ *
357
+ * @return bool
358
+ */
359
+ abstract function is_plugin_new_install();
360
+
361
  #region Marketing ------------------------------------------------------------------
362
 
363
  /**
lib/freemius/includes/class-freemius.php CHANGED
@@ -16,7 +16,7 @@
16
  *
17
  * @var string
18
  */
19
- public $version = '1.1.5';
20
 
21
  #region Plugin Info
22
 
@@ -114,6 +114,12 @@
114
  */
115
  private $_has_addons;
116
 
 
 
 
 
 
 
117
  /**
118
  * @var FS_Key_Value_Storage
119
  */
@@ -185,6 +191,13 @@
185
  */
186
  private $_admin_notices;
187
 
 
 
 
 
 
 
 
188
  /**
189
  * @var FS_Logger
190
  * @since 1.0.0
@@ -311,9 +324,9 @@
311
  * @param string $sdk_prev_version
312
  * @param string $sdk_version
313
  */
314
- function _data_migration($sdk_prev_version, $sdk_version) {
315
- if ( version_compare($sdk_prev_version, '1.1.5', '<' ) &&
316
- version_compare($sdk_version, '1.1.5', '>=')
317
  ) {
318
  // On version 1.1.5 merged connectivity and is_on data.
319
  if ( isset( $this->_storage->connectivity_test ) ) {
@@ -364,7 +377,7 @@
364
 
365
  $this->add_action( 'after_plans_sync', array( &$this, '_check_for_trial_plans' ) );
366
 
367
- $this->add_action('sdk_version_update', array(&$this, '_data_migration'), WP_FS__DEFAULT_PRIORITY, 2);
368
  }
369
 
370
  /**
@@ -466,14 +479,14 @@
466
  function _get_uninstall_reasons( $user_type = 'long-term' ) {
467
  $reason_found_better_plugin = array(
468
  'id' => 2,
469
- 'text' => __fs( 'reason-found-a-better-plugin' ),
470
  'input_type' => 'textfield',
471
- 'input_placeholder' => __fs( 'placeholder-plugin-name' )
472
  );
473
 
474
  $reason_other = array(
475
  'id' => 7,
476
- 'text' => __fs( 'reason-other' ),
477
  'input_type' => 'textfield',
478
  'input_placeholder' => ''
479
  );
@@ -481,26 +494,26 @@
481
  $long_term_user_reasons = array(
482
  array(
483
  'id' => 1,
484
- 'text' => __fs( 'reason-no-longer-needed' ),
485
  'input_type' => '',
486
  'input_placeholder' => ''
487
  ),
488
  $reason_found_better_plugin,
489
  array(
490
  'id' => 3,
491
- 'text' => __fs( 'reason-needed-for-a-short-period' ),
492
  'input_type' => '',
493
  'input_placeholder' => ''
494
  ),
495
  array(
496
  'id' => 4,
497
- 'text' => __fs( 'reason-broke-my-site' ),
498
  'input_type' => '',
499
  'input_placeholder' => ''
500
  ),
501
  array(
502
  'id' => 5,
503
- 'text' => __fs( 'reason-suddenly-stopped-working' ),
504
  'input_type' => '',
505
  'input_placeholder' => ''
506
  )
@@ -509,9 +522,9 @@
509
  if ( $this->is_paying() ) {
510
  $long_term_user_reasons[] = array(
511
  'id' => 6,
512
- 'text' => __fs( 'reason-cant-pay-anymore' ),
513
  'input_type' => 'textfield',
514
- 'input_placeholder' => __fs( 'placeholder-comfortable-price' )
515
  );
516
  }
517
 
@@ -522,13 +535,13 @@
522
  'non-registered-and-non-anonymous-short-term' => array(
523
  array(
524
  'id' => 8,
525
- 'text' => __fs( 'reason-didnt-work' ),
526
  'input_type' => '',
527
  'input_placeholder' => ''
528
  ),
529
  array(
530
  'id' => 9,
531
- 'text' => __fs( 'reason-dont-like-to-share-my-information' ),
532
  'input_type' => '',
533
  'input_placeholder' => ''
534
  ),
@@ -538,34 +551,34 @@
538
  'short-term' => array(
539
  array(
540
  'id' => 10,
541
- 'text' => __fs( 'reason-couldnt-make-it-work' ),
542
  'input_type' => '',
543
  'input_placeholder' => ''
544
  ),
545
  $reason_found_better_plugin,
546
  array(
547
  'id' => 11,
548
- 'text' => __fs( 'reason-great-but-need-specific-feature' ),
549
  'input_type' => 'textarea',
550
- 'input_placeholder' => __fs( 'placeholder-feature' )
551
  ),
552
  array(
553
  'id' => 12,
554
- 'text' => __fs( 'reason-not-working' ),
555
  'input_type' => 'textarea',
556
- 'input_placeholder' => __fs( 'placeholder-share-what-didnt-work' )
557
  ),
558
  array(
559
  'id' => 13,
560
- 'text' => __fs( 'reason-not-what-i-was-looking-for' ),
561
  'input_type' => 'textarea',
562
- 'input_placeholder' => __fs( 'placeholder-what-youve-been-looking-for' )
563
  ),
564
  array(
565
  'id' => 14,
566
- 'text' => __fs( 'reason-didnt-work-as-expected' ),
567
  'input_type' => 'textarea',
568
- 'input_placeholder' => __fs( 'placeholder-what-did-you-expect' )
569
  ),
570
  $reason_other
571
  )
@@ -608,11 +621,10 @@
608
  * @since 1.0.6
609
  *
610
  * @return string
 
 
611
  */
612
  private function _find_caller_plugin_file() {
613
- $bt = debug_backtrace();
614
- $backtrace_entries_count = count( $bt );
615
-
616
  // Try to load the cached value of the file path.
617
  if ( isset( $this->_storage->plugin_main_file ) ) {
618
  if ( file_exists( $this->_storage->plugin_main_file->path ) ) {
@@ -620,33 +632,7 @@
620
  }
621
  }
622
 
623
- /**
624
- * All the code below will be executed once on activation.
625
- * If the user changes the main plugin's file name, the file_exists()
626
- * will catch it.
627
- */
628
- self::require_plugin_essentials();
629
-
630
- $all_plugins = get_plugins();
631
- $all_plugins_paths = array();
632
-
633
- // Get active plugin's main files real full names (might be symlinks).
634
- foreach ( $all_plugins as $relative_path => &$data ) {
635
- $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
636
- }
637
-
638
- $plugin_file = null;
639
- for ( $i = 1; $i < $backtrace_entries_count; $i ++ ) {
640
- if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
641
- $plugin_file = $bt[ $i ]['file'];
642
- break;
643
- }
644
- }
645
-
646
- if ( is_null( $plugin_file ) ) {
647
- // Throw an error to the developer in case of some edge case dev environment.
648
- wp_die( __fs( 'failed-finding-main-path' ), __fs( 'error' ), array( 'back_link' => true ) );
649
- }
650
 
651
  $this->_storage->plugin_main_file = (object) array(
652
  'path' => fs_normalize_path( $plugin_file ),
@@ -818,12 +804,12 @@
818
 
819
  self::$_accounts = FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
820
 
 
 
821
  // Configure which Freemius powered plugins should be auto updated.
822
  // add_filter( 'auto_update_plugin', '_include_plugins_in_auto_update', 10, 2 );
823
 
824
- if ( WP_FS__DEV_MODE ) {
825
- add_action( 'admin_menu', array( 'Freemius', 'add_debug_page' ) );
826
- }
827
 
828
  self::$_statics_loaded = true;
829
  }
@@ -835,15 +821,34 @@
835
  * @since 1.0.8
836
  */
837
  static function add_debug_page() {
 
 
 
 
838
  self::$_static_logger->entrance();
839
 
840
- $hook = add_object_page(
841
- __fs( 'freemius-debug' ),
842
- __fs( 'freemius-debug' ),
843
- 'manage_options',
844
- 'freemius',
845
- array( 'Freemius', '_debug_page_render' )
846
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
 
848
  add_action( "load-$hook", array( 'Freemius', '_debug_page_actions' ) );
849
  }
@@ -853,6 +858,8 @@
853
  * @since 1.0.8
854
  */
855
  static function _debug_page_actions() {
 
 
856
  if ( fs_request_is_action( 'delete_all_accounts' ) ) {
857
  check_admin_referer( 'delete_all_accounts' );
858
 
@@ -893,12 +900,15 @@
893
  /**
894
  * Check if Freemius should be turned on for the current plugin install.
895
  *
 
 
 
896
  * @author Vova Feldman (@svovaf)
897
  * @since 1.0.9
898
  *
899
  * @return bool
900
  */
901
- private function is_on() {
902
  self::$_static_logger->entrance();
903
 
904
  if ( isset( $this->_is_on ) ) {
@@ -909,8 +919,10 @@
909
  if ( $this->is_registered() || $this->is_pending_activation() ) {
910
  $this->_is_on = true;
911
 
912
- return $this->_is_on;
913
  }
 
 
914
  }
915
 
916
  /**
@@ -923,8 +935,8 @@
923
  *
924
  * @return bool
925
  */
926
- private function has_api_connectivity($flush = false) {
927
- if (!$flush && isset( $this->_has_api_connection ) ) {
928
  return $this->_has_api_connection;
929
  }
930
 
@@ -937,24 +949,25 @@
937
  unset( $this->_storage->connectivity_test );
938
  }
939
 
940
- if (isset( $this->_storage->connectivity_test ) ) {
941
- if ( $_SERVER['HTTP_HOST'] == $this->_storage->connectivity_test['host'] &&
942
- $_SERVER['SERVER_ADDR'] == $this->_storage->connectivity_test['server_ip']
 
943
  ) {
944
  if ( ( $this->_storage->connectivity_test['is_connected'] &&
945
  $this->_storage->connectivity_test['is_active'] ) ||
946
- (!$flush &&
947
- $version == $this->_storage->connectivity_test['version'])
948
  ) {
949
  $this->_has_api_connection = $this->_storage->connectivity_test['is_connected'];
950
- $this->_is_on = $this->_storage->connectivity_test['is_active'];
951
 
952
  return $this->_has_api_connection;
953
  }
954
  }
955
  }
956
 
957
- $is_update = $this->apply_filters( 'is_plugin_update', !$this->is_plugin_new_install() );
958
 
959
  if ( WP_FS__SIMULATE_NO_API_CONNECTIVITY ) {
960
  $is_connected = false;
@@ -982,7 +995,7 @@
982
  $this->_storage->connectivity_test = array(
983
  'is_connected' => $is_connected,
984
  'host' => $_SERVER['HTTP_HOST'],
985
- 'server_ip' => $_SERVER['SERVER_ADDR'],
986
  'is_active' => $is_active,
987
  'timestamp' => WP_FS__SCRIPT_START_TIME,
988
  // Last version with connectivity attempt.
@@ -990,7 +1003,7 @@
990
  );
991
 
992
  $this->_has_api_connection = $is_connected;
993
- $this->_is_on = $is_active;
994
 
995
  return $this->_has_api_connection;
996
  }
@@ -1049,133 +1062,133 @@
1049
  switch ( $api_result->error->code ) {
1050
  case 'curl_missing':
1051
  $message = sprintf(
1052
- __fs( 'x-requires-access-to-api', 'freemius' ) . ' ' .
1053
- __fs( 'curl-missing-message' ) . ' ' .
1054
  ' %s',
1055
  '<b>' . $this->get_plugin_name() . '</b>',
1056
  sprintf(
1057
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1058
  sprintf(
1059
  '<a class="fs-resolve" data-type="curl" href="#"><b>%s</b></a>%s',
1060
- __fs( 'curl-missing-no-clue-title' ),
1061
  ' - ' . sprintf(
1062
- __fs( 'curl-missing-no-clue-desc' ),
1063
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1064
  )
1065
  ),
1066
  sprintf(
1067
  '<b>%s</b> - %s',
1068
- __fs( 'sysadmin-title' ),
1069
- __fs( 'curl-missing-sysadmin-desc' )
1070
  ),
1071
  sprintf(
1072
  '<a href="%s"><b>%s</b></a>%s',
1073
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1074
- __fs( 'deactivate-plugin-title' ),
1075
- ' - ' . __fs( 'deactivate-plugin-desc', 'freemius' )
1076
  )
1077
  )
1078
  );
1079
  break;
1080
  case 'cloudflare_ddos_protection':
1081
  $message = sprintf(
1082
- __fs( 'x-requires-access-to-api', 'freemius' ) . ' ' .
1083
- __fs( 'cloudflare-blocks-connection-message' ) . ' ' .
1084
- __fs( 'happy-to-resolve-issue-asap' ) .
1085
  ' %s',
1086
  '<b>' . $this->get_plugin_name() . '</b>',
1087
  sprintf(
1088
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1089
  sprintf(
1090
  '<a class="fs-resolve" data-type="cloudflare" href="#"><b>%s</b></a>%s',
1091
- __fs( 'fix-issue-title' ),
1092
  ' - ' . sprintf(
1093
- __fs( 'fix-issue-desc' ),
1094
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1095
  )
1096
  ),
1097
  sprintf(
1098
  '<a href="%s" target="_blank"><b>%s</b></a>%s',
1099
  sprintf( 'https://wordpress.org/plugins/%s/download/', $this->_slug ),
1100
- __fs( 'install-previous-title' ),
1101
- ' - ' . __fs( 'install-previous-desc' )
1102
  ),
1103
  sprintf(
1104
  '<a href="%s"><b>%s</b></a>%s',
1105
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1106
- __fs( 'deactivate-plugin-title' ),
1107
- ' - ' . __fs( 'deactivate-plugin-desc', 'freemius' )
1108
  )
1109
  )
1110
  );
1111
  break;
1112
  case 'squid_cache_block':
1113
  $message = sprintf(
1114
- __fs( 'x-requires-access-to-api', 'freemius' ) . ' ' .
1115
- __fs( 'squid-blocks-connection-message' ) .
1116
  ' %s',
1117
  '<b>' . $this->get_plugin_name() . '</b>',
1118
  sprintf(
1119
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1120
  sprintf(
1121
  '<a class="fs-resolve" data-type="squid" href="#"><b>%s</b></a>%s',
1122
- __fs( 'squid-no-clue-title' ),
1123
  ' - ' . sprintf(
1124
- __fs( 'squid-no-clue-desc' ),
1125
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1126
  )
1127
  ),
1128
  sprintf(
1129
  '<b>%s</b> - %s',
1130
- __fs( 'sysadmin-title' ),
1131
  sprintf(
1132
- __fs( 'squid-sysadmin-desc' ),
1133
  // We use a filter since the plugin might require additional API connectivity.
1134
  '<b>' . implode( ', ', $this->apply_filters( 'api_domains', array( 'api.freemius.com' ) ) ) . '</b>' )
1135
  ),
1136
  sprintf(
1137
  '<a href="%s"><b>%s</b></a>%s',
1138
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1139
- __fs( 'deactivate-plugin-title' ),
1140
- ' - ' . __fs( 'deactivate-plugin-desc', 'freemius' )
1141
  )
1142
  )
1143
  );
1144
  break;
1145
  default:
1146
- $message = __fs( 'connectivity-test-fails-message' );
1147
  break;
1148
  }
1149
  }
1150
 
1151
  if ( false === $message ) {
1152
  $message = sprintf(
1153
- __fs( 'x-requires-access-to-api', 'freemius' ) . ' ' .
1154
- __fs( 'connectivity-test-fails-message' ) . ' ' .
1155
- __fs( 'happy-to-resolve-issue-asap' ) .
1156
  ' %s',
1157
  '<b>' . $this->get_plugin_name() . '</b>',
1158
  sprintf(
1159
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1160
  sprintf(
1161
  '<a class="fs-resolve" data-type="general" href="#"><b>%s</b></a>%s',
1162
- __fs( 'fix-issue-title' ),
1163
  ' - ' . sprintf(
1164
- __fs( 'fix-issue-desc' ),
1165
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1166
  )
1167
  ),
1168
  sprintf(
1169
  '<a href="%s" target="_blank"><b>%s</b></a>%s',
1170
  sprintf( 'https://wordpress.org/plugins/%s/download/', $this->_slug ),
1171
- __fs( 'install-previous-title' ),
1172
- ' - ' . __fs( 'install-previous-desc' )
1173
  ),
1174
  sprintf(
1175
  '<a href="%s"><b>%s</b></a>%s',
1176
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1177
- __fs( 'deactivate-plugin-title' ),
1178
- ' - ' . __fs( 'deactivate-plugin-desc', 'freemius' )
1179
  )
1180
  )
1181
  );
@@ -1184,7 +1197,7 @@
1184
  $this->_admin_notices->add_sticky(
1185
  $message,
1186
  'failed_connect_api',
1187
- __fs( 'oops' ) . '...',
1188
  'error'
1189
  );
1190
  }
@@ -1272,7 +1285,7 @@
1272
 
1273
  $this->_admin_notices->add_sticky(
1274
  sprintf(
1275
- __fs( 'fix-request-sent-message' ),
1276
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1277
  ),
1278
  'server_details_sent'
@@ -1387,6 +1400,8 @@
1387
  );
1388
  }
1389
 
 
 
1390
  // Generate the default email sections.
1391
  $sections = array(
1392
  'sdk' => array(
@@ -1413,7 +1428,7 @@
1413
  ),
1414
  'server_addr' => array(
1415
  'SERVER_ADDR',
1416
- ( ! empty( $_SERVER['SERVER_ADDR'] ) ? '<a href="http://www.projecthoneypot.org/ip_' . $_SERVER['SERVER_ADDR'] . '">' . $_SERVER['SERVER_ADDR'] . '</a>' : '' )
1417
  )
1418
  )
1419
  ),
@@ -1465,6 +1480,13 @@
1465
  ) );
1466
  }
1467
 
 
 
 
 
 
 
 
1468
  private function _get_option( &$options, $key, $default = false ) {
1469
  return ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
1470
  }
@@ -1550,8 +1572,22 @@
1550
  $this->_has_paid_plans = $this->_get_bool_option( $plugin_info, 'has_paid_plans', true );
1551
  $this->_is_org_compliant = $this->_get_bool_option( $plugin_info, 'is_org_compliant', true );
1552
  $this->_enable_anonymous = $this->_get_bool_option( $plugin_info, 'enable_anonymous', true );
 
1553
 
1554
  if ( ! $this->is_registered() ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1555
  if ( ! $this->has_api_connectivity() ) {
1556
  if ( is_admin() && $this->_admin_notices->has_sticky( 'failed_connect_api' ) ) {
1557
  if ( ! $this->_enable_anonymous ) {
@@ -1607,10 +1643,10 @@
1607
  if ( ! $this->is_parent_plugin_installed() ) {
1608
  $this->_admin_notices->add(
1609
  ( is_string( $parent_name ) ?
1610
- sprintf( __fs( 'addon-cannot-run-without-x' ), $this->get_plugin_name(), $parent_name ) :
1611
- sprintf( __fs( 'addon-x-cannot-run-without-parent' ), $this->get_plugin_name() )
1612
  ),
1613
- __fs( 'oops' ) . '...',
1614
  'error'
1615
  );
1616
 
@@ -1643,14 +1679,17 @@
1643
  add_action( 'install_plugins_pre_plugin-information', 'fs_install_plugin_information' );
1644
 
1645
  // Override request for plugin information for Add-ons.
1646
- add_filter( 'fs_plugins_api', array( &$this, '_get_addon_info_filter' ), WP_FS__DEFAULT_PRIORITY, 3 );
1647
- } else {
1648
- if ( $this->is_paying() || $this->_has_addons() ) {
1649
- new FS_Plugin_Updater( $this );
1650
- }
1651
  }
1652
  }
1653
 
 
 
 
 
1654
  // if ( $this->is_registered() ||
1655
  // $this->is_anonymous() ||
1656
  // $this->is_pending_activation()
@@ -1718,9 +1757,9 @@
1718
  ) );
1719
 
1720
  $this->_admin_notices->add_sticky(
1721
- __fs( 'premium-activated-message' ),
1722
  'premium_activated',
1723
- __fs( 'woot' ) . '!'
1724
  );
1725
  } else {
1726
  // Activated free code (after had the premium before).
@@ -1729,14 +1768,14 @@
1729
  if ( $this->is_paying() && ! $this->is_premium() ) {
1730
  $this->_admin_notices->add_sticky(
1731
  sprintf(
1732
- __fs( 'you-have-x-license' ),
1733
  $this->_site->plan->title
1734
  ) . ' ' . $this->_get_latest_download_link( sprintf(
1735
- __fs( 'download-x-version-now' ),
1736
  $this->_site->plan->title
1737
  ) ),
1738
  'plan_upgraded',
1739
- __fs( 'yee-haw' ) . '!'
1740
  );
1741
  }
1742
  }
@@ -1816,7 +1855,10 @@
1816
  }
1817
 
1818
  if ( ! empty( $selected_addon->info->screenshots ) ) {
1819
- $view_vars = array( 'screenshots' => $selected_addon->info->screenshots );
 
 
 
1820
  $data->sections['screenshots'] = fs_get_template( '/plugin-info/screenshots.php', $view_vars );
1821
  }
1822
 
@@ -1874,7 +1916,10 @@
1874
  $data->plans = $plans;
1875
 
1876
  if ( $has_features ) {
1877
- $view_vars = array( 'plans' => $plans );
 
 
 
1878
  $data->sections['features'] = fs_get_template( '/plugin-info/features.php', $view_vars );
1879
  }
1880
  }
@@ -2114,6 +2159,11 @@
2114
  return false;
2115
  }
2116
 
 
 
 
 
 
2117
  $sync_timestamp = $this->_storage->get( 'sync_timestamp' );
2118
 
2119
  if ( ! is_numeric( $sync_timestamp ) || $sync_timestamp >= time() ) {
@@ -2130,8 +2180,10 @@
2130
  // Initiate background plan sync.
2131
  $this->_sync_license( true );
2132
 
2133
- // Check for plugin updates.
2134
- $this->_check_updates( true );
 
 
2135
  }
2136
 
2137
  if ( ! $this->is_addon() ) {
@@ -2167,7 +2219,7 @@
2167
 
2168
  $this->_admin_notices->add_sticky(
2169
  sprintf(
2170
- __fs( 'pending-activation-message' ),
2171
  '<b>' . $this->get_plugin_name() . '</b>',
2172
  '<b>' . $email . '</b>'
2173
  ),
@@ -2221,10 +2273,10 @@
2221
  // Show notice for new plugin installations.
2222
  $this->_admin_notices->add(
2223
  sprintf(
2224
- __fs( 'you-are-step-away' ),
2225
  sprintf( '<b><a href="%s">%s</a></b>',
2226
  $this->get_activation_url(),
2227
- sprintf( __fs( 'activate-x-now' ), $this->get_plugin_name() )
2228
  )
2229
  ),
2230
  '',
@@ -2237,10 +2289,10 @@
2237
  // Show notice for new plugin installations.
2238
  $this->_admin_notices->add_sticky(
2239
  sprintf(
2240
- __fs( 'few-plugin-tweaks' ),
2241
  sprintf( '<b><a href="%s">%s</a></b>',
2242
  $this->get_activation_url(),
2243
- sprintf( __fs( 'optin-x-now' ), $this->get_plugin_name() )
2244
  )
2245
  ),
2246
  'connect_account',
@@ -2248,20 +2300,6 @@
2248
  'update-nag'
2249
  );
2250
  }
2251
-
2252
- if ( $this->has_filter( 'optin_pointer_element' ) ) {
2253
- // Don't show admin nag if plugin update.
2254
- wp_enqueue_script( 'wp-pointer' );
2255
- wp_enqueue_style( 'wp-pointer' );
2256
-
2257
- $this->_enqueue_connect_essentials();
2258
-
2259
- add_action( 'admin_print_footer_scripts', array(
2260
- $this,
2261
- '_add_connect_pointer_script'
2262
- ) );
2263
- }
2264
-
2265
  }
2266
  }
2267
  }
@@ -2285,60 +2323,6 @@
2285
 
2286
  fs_enqueue_local_style( 'fs_connect', '/admin/connect.css' );
2287
  }
2288
-
2289
- /**
2290
- * Add connect / opt-in pointer.
2291
- *
2292
- * @author Vova Feldman (@svovaf)
2293
- * @since 1.1.4
2294
- */
2295
- function _add_connect_pointer_script() {
2296
- $vars = array( 'slug' => $this->_slug );
2297
- $pointer_content = fs_get_template(
2298
- $this->is_pending_activation() ?
2299
- 'pending-activation.php' :
2300
- 'connect.php',
2301
- $vars
2302
- );
2303
- ?>
2304
- <script type="text/javascript">// <![CDATA[
2305
- jQuery(document).ready(function ($) {
2306
- if ('undefined' !== typeof(jQuery().pointer)) {
2307
-
2308
- var element = <?php echo $this->apply_filters('optin_pointer_element', '$("#non_existing_element");') ?>;
2309
-
2310
- if (element.length > 0) {
2311
- var optin = $(element).pointer($.extend(true, {}, {
2312
- content : <?php echo json_encode($pointer_content) ?>,
2313
- position : {
2314
- edge : 'left',
2315
- align: 'center'
2316
- },
2317
- buttons : function () {
2318
- // Don't show pointer buttons.
2319
- return '';
2320
- },
2321
- pointerWidth: 482
2322
- }, <?php echo $this->apply_filters('optin_pointer_options_json', '{}') ?>));
2323
-
2324
- <?php
2325
- echo $this->apply_filters('optin_pointer_execute', "
2326
-
2327
- optin.pointer('open');
2328
-
2329
- // Tag the opt-in pointer with custom class.
2330
- $('.wp-pointer #fs_connect')
2331
- .parents('.wp-pointer.wp-pointer-top')
2332
- .addClass('fs-opt-in-pointer');
2333
-
2334
- ", 'element', 'optin') ?>
2335
- }
2336
- }
2337
- });
2338
- // ]]></script>
2339
- <?php
2340
- }
2341
-
2342
  /**
2343
  * Return current page's URL.
2344
  *
@@ -2440,14 +2424,15 @@
2440
  }
2441
 
2442
  /**
 
 
2443
  * @author Vova Feldman (@svovaf)
2444
  * @since 1.1.5
2445
  *
2446
  * @return bool
2447
  */
2448
- private function is_plugin_new_install()
2449
- {
2450
- return isset($this->_storage->is_plugin_new_install) &&
2451
  $this->_storage->is_plugin_new_install;
2452
  }
2453
 
@@ -2481,8 +2466,8 @@
2481
  deactivate_plugins( $this->_free_plugin_basename );
2482
 
2483
  $this->_admin_notices->add(
2484
- sprintf( __fs( 'successful-version-upgrade-message' ), sprintf( '<b>%s</b>', $this->_plugin->title ) ),
2485
- __fs( 'woot' ) . '!'
2486
  );
2487
  }
2488
  } else if ( $this->is_anonymous() ) {
@@ -2516,7 +2501,7 @@
2516
  $this->_storage->is_plugin_new_install = empty( $this->_storage->plugin_last_version );
2517
  }
2518
 
2519
- if ( $this->has_api_connectivity(true) ) {
2520
  // Store hint that the plugin was just activated to enable auto-redirection to settings.
2521
  add_option( "fs_{$this->_slug}_activated", true );
2522
  }
@@ -2581,13 +2566,16 @@
2581
  }
2582
 
2583
  $this->_admin_notices->clear_all_sticky();
 
 
 
2584
 
2585
  if ( ! $this->has_api_connectivity() ) {
2586
  // Reset connectivity test cache.
2587
  unset( $this->_storage->connectivity_test );
2588
  }
2589
 
2590
- if (!isset($this->_storage->is_plugin_new_install)) {
2591
  // Remember that plugin was already installed.
2592
  $this->_storage->is_plugin_new_install = false;
2593
  }
@@ -2601,6 +2589,25 @@
2601
 
2602
  // Clear API cache on deactivation.
2603
  FS_Api::clear_cache();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2604
  }
2605
 
2606
  /**
@@ -2617,6 +2624,9 @@
2617
  'timestamp' => WP_FS__SCRIPT_START_TIME,
2618
  'version' => $this->get_plugin_version(),
2619
  );
 
 
 
2620
  }
2621
 
2622
  /**
@@ -2656,16 +2666,16 @@
2656
  private function update_plugin_version_event() {
2657
  $this->_logger->entrance( 'slug = ' . $this->_slug );
2658
 
2659
- $this->_site->version = $this->get_plugin_version();
2660
-
2661
  // Send update event.
2662
  $site = $this->send_install_update( array(), true );
2663
 
2664
  if ( false !== $site && ! $this->is_api_error( $site ) ) {
2665
  $this->_site = new FS_Site( $site );
2666
  $this->_site->plan = $this->_get_plan_by_id( $site->plan_id );
2667
- $this->_store_site( true );
2668
  }
 
 
 
2669
  }
2670
 
2671
  /**
@@ -3270,6 +3280,21 @@
3270
  return $addons[ $this->_plugin->id ];
3271
  }
3272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3273
  /**
3274
  * Get add-on by ID (from local data).
3275
  *
@@ -4180,7 +4205,7 @@
4180
  return;
4181
  }
4182
 
4183
- $this->_clean_admin_content_section();
4184
 
4185
  if ( fs_request_is_action( 'activate' ) && fs_request_is_post() ) {
4186
  // check_admin_referer( 'activate_' . $this->_plugin->public_key );
@@ -4359,10 +4384,12 @@
4359
  function setup_account( FS_User $user, FS_Site $site, $redirect = true ) {
4360
  $this->_user = $user;
4361
  $this->_site = $site;
 
 
 
4362
  $this->_enrich_site_plan( false );
4363
 
4364
  $this->_set_account( $user, $site );
4365
- $this->_sync_plans();
4366
 
4367
  if ( $this->is_trial() ) {
4368
  // Store trial plan information.
@@ -4384,7 +4411,7 @@
4384
 
4385
  if ( ! $this->is_paying() ) {
4386
  $this->_admin_notices->add_sticky(
4387
- sprintf( __fs( 'plugin-x-activation-message' ), '<b>' . $this->get_plugin_name() . '</b>' ),
4388
  'activation_complete'
4389
  );
4390
  }
@@ -4393,14 +4420,14 @@
4393
  if ( $this->is_paying() && ! $this->is_premium() ) {
4394
  $this->_admin_notices->add_sticky(
4395
  sprintf(
4396
- __fs( 'activation-with-plan-x-message' ),
4397
  $this->_site->plan->title
4398
  ) . ' ' . $this->_get_latest_download_link( sprintf(
4399
- __fs( 'download-latest-x-version' ),
4400
  $this->_site->plan->title
4401
  ) ),
4402
  'plan_upgraded',
4403
- __fs( 'yee-haw' ) . '!'
4404
  );
4405
  }
4406
 
@@ -4441,6 +4468,8 @@
4441
  * @since 1.0.7
4442
  */
4443
  function _install_with_new_user() {
 
 
4444
  if ( $this->is_registered() ) {
4445
  return;
4446
  }
@@ -4493,6 +4522,8 @@
4493
  * @since 1.0.7
4494
  */
4495
  function _install_with_current_user() {
 
 
4496
  if ( $this->is_registered() ) {
4497
  return;
4498
  }
@@ -4522,9 +4553,9 @@
4522
 
4523
  if ( isset( $install->error ) ) {
4524
  $this->_admin_notices->add(
4525
- sprintf( __fs( 'could-not-activate-x' ), $this->get_plugin_name() ) . ' ' .
4526
- __fs( 'contact-us-with-error-message' ) . ' ' . '<b>' . $install->error->message . '</b>',
4527
- __fs( 'oops' ) . '...',
4528
  'error'
4529
  );
4530
 
@@ -4567,9 +4598,9 @@
4567
 
4568
  if ( isset( $addon_install->error ) ) {
4569
  $this->_admin_notices->add(
4570
- sprintf( __fs( 'could-not-activate-x' ), $this->get_plugin_name() ) . ' ' .
4571
- __fs( 'contact-us-with-error-message' ) . ' ' . '<b>' . $addon_install->error->message . '</b>',
4572
- __fs( 'oops' ) . '...',
4573
  'error'
4574
  );
4575
 
@@ -4747,7 +4778,7 @@
4747
 
4748
  if ( $this->_menu->is_activation_page() ) {
4749
  // Clean admin page from distracting content.
4750
- $this->_clean_admin_content_section();
4751
  }
4752
 
4753
  if ( false !== $hook ) {
@@ -4787,9 +4818,9 @@
4787
  if ( $this->is_registered() ) {
4788
  // Add user account page.
4789
  $this->add_submenu_item(
4790
- __fs( 'account' ),
4791
  array( &$this, '_account_page_render' ),
4792
- $this->get_plugin_name() . ' &ndash; ' . __fs( 'account' ),
4793
  'manage_options',
4794
  'account',
4795
  array( &$this, '_account_page_load' ),
@@ -4800,21 +4831,21 @@
4800
 
4801
  // Add contact page.
4802
  $this->add_submenu_item(
4803
- __fs( 'contact-us' ),
4804
  array( &$this, '_contact_page_render' ),
4805
- $this->get_plugin_name() . ' &ndash; ' . __fs( 'contact-us' ),
4806
  'manage_options',
4807
  'contact',
4808
- array( &$this, '_clean_admin_content_section' ),
4809
  WP_FS__DEFAULT_PRIORITY,
4810
  $this->_menu->is_submenu_item_visible( 'contact' )
4811
  );
4812
 
4813
  if ( $this->_has_addons() ) {
4814
  $this->add_submenu_item(
4815
- __fs( 'add-ons' ),
4816
  array( &$this, '_addons_page_render' ),
4817
- $this->get_plugin_name() . ' &ndash; ' . __fs( 'add-ons' ),
4818
  'manage_options',
4819
  'addons',
4820
  array( &$this, '_addons_page_load' ),
@@ -4823,18 +4854,21 @@
4823
  );
4824
  }
4825
 
 
 
 
 
 
4826
  // Add upgrade/pricing page.
4827
  $this->add_submenu_item(
4828
- ( $this->is_paying() ? __fs( 'pricing' ) : __fs( 'upgrade' ) . '&nbsp;&nbsp;&#x27a4;' ),
4829
  array( &$this, '_pricing_page_render' ),
4830
- $this->get_plugin_name() . ' &ndash; ' . __fs( 'pricing' ),
4831
  'manage_options',
4832
  'pricing',
4833
- array( &$this, '_clean_admin_content_section' ),
4834
  WP_FS__LOWEST_PRIORITY,
4835
- // If user don't have paid plans, add pricing page
4836
- // to support add-ons checkout but don't add the submenu item.
4837
- $this->_menu->is_submenu_item_visible( 'pricing' ) && ( $this->has_paid_plan() || ( isset( $_GET['page'] ) && $this->_menu->get_slug( 'pricing' ) == $_GET['page'] ) )
4838
  );
4839
  }
4840
  }
@@ -4951,8 +4985,8 @@
4951
  if ( $this->is_registered() ) {
4952
  if ( $this->_menu->is_submenu_item_visible( 'support' ) ) {
4953
  $this->add_submenu_link_item(
4954
- __fs( 'support-forum' ),
4955
- 'https://wordpress.org/support/plugin/' . $this->_slug,
4956
  'wp-support-forum',
4957
  'read',
4958
  50
@@ -5134,11 +5168,9 @@
5134
  $this->_logger->entrance( $tag );
5135
 
5136
  $args = func_get_args();
 
5137
 
5138
- return call_user_func_array( 'apply_filters', array_merge(
5139
- array( 'fs_' . $tag . '_' . $this->_slug ),
5140
- array_slice( $args, 1 ) )
5141
- );
5142
  }
5143
 
5144
  /**
@@ -5168,6 +5200,10 @@
5168
  *
5169
  * @param string $tag
5170
  * @param callable|bool $function_to_check Optional. The callback to check for. Default false.
 
 
 
 
5171
  */
5172
  function has_filter( $tag, $function_to_check = false ) {
5173
  $this->_logger->entrance( $tag );
@@ -5175,6 +5211,20 @@
5175
  return has_filter( 'fs_' . $tag . '_' . $this->_slug, $function_to_check );
5176
  }
5177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5178
  /* Account Page
5179
  ------------------------------------------------------------------------------------------------------------------*/
5180
  /**
@@ -5385,14 +5435,26 @@
5385
  $this->_user->last = $user->last;
5386
  $this->_user->email = $user->email;
5387
 
5388
- if ( ( ! isset( $this->_user->is_verified ) || false === $this->_user->is_verified ) && $user->is_verified ) {
5389
- $this->_user->is_verified = $user->is_verified;
 
 
 
 
5390
 
5391
  $this->do_action( 'account_email_verified', $user->email );
5392
 
5393
  $this->_admin_notices->add(
5394
- __fs( 'email-verified-message' ),
5395
- __fs( 'right-on' ) . '!'
 
 
 
 
 
 
 
 
5396
  );
5397
  }
5398
 
@@ -5400,6 +5462,20 @@
5400
  $this->_store_user();
5401
 
5402
  $this->do_action( 'after_account_user_sync', $user );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5403
  }
5404
  }
5405
 
@@ -5773,22 +5849,22 @@
5773
  $this->_admin_notices->add_sticky(
5774
  FS_Plan_Manager::instance()->has_free_plan( $plans ) ?
5775
  sprintf(
5776
- __fs( 'addon-successfully-upgraded-message' ),
5777
  $addon->title
5778
  ) . ' ' . $this->_get_latest_download_link(
5779
- __fs( 'download-latest-version' ),
5780
  $addon_id
5781
  )
5782
  :
5783
  sprintf(
5784
- __fs( 'addon-successfully-purchased-message' ),
5785
  $addon->title
5786
  ) . ' ' . $this->_get_latest_download_link(
5787
- __fs( 'download-latest-version' ),
5788
  $addon_id
5789
  ),
5790
  'addon_plan_upgraded_' . $addon->slug,
5791
- __fs( 'yee-haw' ) . '!'
5792
  );
5793
  }
5794
  }
@@ -5814,30 +5890,45 @@
5814
  $plan_change = 'none';
5815
 
5816
  if ( $this->is_api_error( $site ) ) {
5817
- $api = $this->get_api_site_scope();
5818
-
5819
- // Try to ping API to see if not blocked.
5820
- if ( ! $api->test() ) {
5821
- // Failed to ping API - blocked!
5822
- $this->_admin_notices->add(
5823
- sprintf(
5824
- __fs( 'server-blocking-access' ),
5825
- $this->get_plugin_name(),
5826
- '<a href="' . $api->get_url() . '" target="_blank">' . $api->get_url() . '</a>'
5827
- ) . '<br> ' . __fs( 'server-error-message' ) . var_export( $site->error, true ),
5828
- __fs( 'oops' ) . '...',
5829
- 'error',
5830
- $background
5831
- );
5832
- } else {
5833
- // Authentication params are broken.
5834
- $this->_admin_notices->add(
5835
- __fs( 'wrong-authentication-param-message' ),
5836
- __fs( 'oops' ) . '...',
5837
- 'error'
5838
- );
 
 
 
 
 
 
 
 
 
 
 
 
5839
  }
5840
  } else {
 
 
 
5841
  $site = new FS_Site( $site );
5842
 
5843
  // Sync licenses.
@@ -5917,19 +6008,19 @@
5917
  if ( ! $background && is_admin() ) {
5918
  $this->_admin_notices->add(
5919
  sprintf(
5920
- __fs( 'plan-did-not-change-message' ) . ' ' .
5921
  sprintf(
5922
  '<a href="%s">%s</a>',
5923
  $this->contact_url(
5924
  'bug',
5925
- sprintf( __fs( 'plan-did-not-change-email-message', 'freemius' ),
5926
  strtoupper( $this->_site->plan->name )
5927
  )
5928
  ),
5929
- __fs( 'contact-us-here' )
5930
  )
5931
  ),
5932
- __fs( 'hmm' ) . '...',
5933
  'error'
5934
  );
5935
  }
@@ -5937,15 +6028,15 @@
5937
  case 'upgraded':
5938
  $this->_admin_notices->add_sticky(
5939
  sprintf(
5940
- __fs( 'plan-upgraded-message' ),
5941
  '<i>' . $this->get_plugin_name() . '</i>'
5942
  ) . ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
5943
- __fs( 'download-latest-x-version' ),
5944
  $this->_site->plan->title
5945
  ) )
5946
  ),
5947
  'plan_upgraded',
5948
- __fs( 'yee-haw' ) . '!'
5949
  );
5950
 
5951
  $this->_admin_notices->remove_sticky( array(
@@ -5958,7 +6049,7 @@
5958
  case 'changed':
5959
  $this->_admin_notices->add_sticky(
5960
  sprintf(
5961
- __fs( 'plan-changed-to-x-message' ),
5962
  $this->_site->plan->title
5963
  ),
5964
  'plan_changed'
@@ -5973,31 +6064,31 @@
5973
  break;
5974
  case 'downgraded':
5975
  $this->_admin_notices->add_sticky(
5976
- sprintf( __fs( 'license-expired-blocking-message' ) ),
5977
  'license_expired',
5978
- __fs( 'hmm' ) . '...'
5979
  );
5980
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
5981
  break;
5982
  case 'expired':
5983
  $this->_admin_notices->add_sticky(
5984
- sprintf( __fs( 'license-expired-non-blocking-message' ), $this->_site->plan->title ),
5985
  'license_expired',
5986
- __fs( 'hmm' ) . '...'
5987
  );
5988
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
5989
  break;
5990
  case 'trial_started':
5991
  $this->_admin_notices->add_sticky(
5992
  sprintf(
5993
- __fs( 'trial-started-message' ),
5994
  '<i>' . $this->get_plugin_name() . '</i>'
5995
  ) . ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
5996
- __fs( 'download-latest-x-version' ),
5997
  $this->_storage->trial_plan->title
5998
  ) ) ),
5999
  'trial_started',
6000
- __fs( 'yee-haw' ) . '!'
6001
  );
6002
 
6003
  $this->_admin_notices->remove_sticky( array(
@@ -6006,9 +6097,9 @@
6006
  break;
6007
  case 'trial_expired':
6008
  $this->_admin_notices->add_sticky(
6009
- __fs( 'trial-expired-message' ),
6010
  'trial_expired',
6011
- __fs( 'hmm' ) . '...'
6012
  );
6013
  $this->_admin_notices->remove_sticky( array(
6014
  'trial_started',
@@ -6044,9 +6135,9 @@
6044
  if ( isset( $license->error ) ) {
6045
  if ( ! $background ) {
6046
  $this->_admin_notices->add(
6047
- __fs( 'license-activation-failed-message' ) . '<br> ' .
6048
- __fs( 'server-error-message' ) . ' ' . var_export( $license->error, true ),
6049
- __fs( 'hmm' ) . '...',
6050
  'error'
6051
  );
6052
  }
@@ -6065,13 +6156,13 @@
6065
 
6066
  if ( ! $background ) {
6067
  $this->_admin_notices->add_sticky(
6068
- __fs( 'license-activated-message' ) .
6069
  ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
6070
- __fs( 'download-latest-x-version' ),
6071
  $this->_site->plan->title
6072
  ) ) ),
6073
  'license_activated',
6074
- __fs( 'yee-haw' ) . '!'
6075
  );
6076
  }
6077
 
@@ -6092,8 +6183,8 @@
6092
 
6093
  if ( ! is_object( $this->_license ) ) {
6094
  $this->_admin_notices->add(
6095
- sprintf( __fs( 'no-active-license-message' ), $this->_site->plan->title ),
6096
- __fs( 'hmm' ) . '...'
6097
  );
6098
 
6099
  return;
@@ -6104,9 +6195,9 @@
6104
 
6105
  if ( isset( $license->error ) ) {
6106
  $this->_admin_notices->add(
6107
- __fs( 'license-deactivation-failed-message' ) . '<br> ' .
6108
- __fs( 'server-error-message' ) . ' ' . var_export( $license->error, true ),
6109
- __fs( 'hmm' ) . '...',
6110
  'error'
6111
  );
6112
 
@@ -6131,8 +6222,8 @@
6131
 
6132
  if ( $show_notice ) {
6133
  $this->_admin_notices->add(
6134
- sprintf( __fs( 'license-deactivation-message' ), $this->_site->plan->title ),
6135
- __fs( 'ok' )
6136
  );
6137
  }
6138
 
@@ -6180,7 +6271,7 @@
6180
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6181
 
6182
  $this->_admin_notices->add(
6183
- sprintf( __fs( 'plan-x-downgraded-message' ),
6184
  $plan->title,
6185
  human_time_diff( time(), strtotime( $this->_license->expiration ) )
6186
  )
@@ -6190,8 +6281,8 @@
6190
  $this->_store_site();
6191
  } else {
6192
  $this->_admin_notices->add(
6193
- __fs( 'plan-downgraded-failure-message' ),
6194
- __fs( 'oops' ) . '...',
6195
  'error'
6196
  );
6197
  }
@@ -6210,8 +6301,8 @@
6210
 
6211
  if ( ! $this->is_trial() ) {
6212
  $this->_admin_notices->add(
6213
- __fs( 'trial-cancel-no-trial-message' ),
6214
- __fs( 'oops' ) . '...',
6215
  'error'
6216
  );
6217
 
@@ -6240,7 +6331,7 @@
6240
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6241
 
6242
  $this->_admin_notices->add(
6243
- sprintf( __fs( 'trial-cancel-message' ), $this->_storage->trial_plan->title )
6244
  );
6245
 
6246
  $this->_admin_notices->remove_sticky( array(
@@ -6256,8 +6347,8 @@
6256
  unset( $this->_storage->trial_plan );
6257
  } else {
6258
  $this->_admin_notices->add(
6259
- __fs( 'trial-cancel-failure-message' ),
6260
- __fs( 'oops' ) . '...',
6261
  'error'
6262
  );
6263
  }
@@ -6481,21 +6572,21 @@
6481
  if ( ! $background ) {
6482
  $this->_admin_notices->add(
6483
  sprintf(
6484
- __fs( 'version-x-released' ) . ' ' . __fS( 'please-download-x' ),
6485
  $update->version,
6486
  sprintf(
6487
  '<a href="%s" target="_blank">%s</a>',
6488
  $this->get_account_url( 'download_latest' ),
6489
- sprintf( __fs( 'latest-x-version' ), $this->_site->plan->title )
6490
  )
6491
  ),
6492
- __fs( 'new' ) . '!'
6493
  );
6494
  }
6495
  } else if ( false === $new_version && ! $background ) {
6496
  $this->_admin_notices->add(
6497
- __fs( 'you-have-latest' ),
6498
- __fs( 'you-are-good' )
6499
  );
6500
  }
6501
 
@@ -6693,7 +6784,7 @@
6693
 
6694
  if ( ! isset( $result->error ) ) {
6695
  $this->_admin_notices->add( sprintf(
6696
- __fs( 'verification-email-sent-message' ),
6697
  sprintf( '<a href="mailto:%1s">%2s</a>', esc_url( $this->_user->email ), $this->_user->email )
6698
  ) );
6699
  } else {
@@ -6820,20 +6911,20 @@
6820
  $candidate_email = fs_request_get( 'candidate_email', '' );
6821
 
6822
  if ( $this->init_change_owner( $candidate_email ) ) {
6823
- $this->_admin_notices->add( sprintf( __fs( 'change-owner-request-sent-x' ), '<b>' . $this->_user->email . '</b>' ) );
6824
  }
6825
  break;
6826
  case 'owner_confirmed':
6827
  $candidate_email = fs_request_get( 'candidate_email', '' );
6828
 
6829
- $this->_admin_notices->add( sprintf( __fs( 'change-owner-request_owner-confirmed' ), '<b>' . $candidate_email . '</b>' ) );
6830
  break;
6831
  case 'candidate_confirmed':
6832
  if ( $this->complete_change_owner() ) {
6833
  $this->_admin_notices->add_sticky(
6834
- sprintf( __fs( 'change-owner-request_candidate-confirmed' ), '<b>' . $this->_user->email . '</b>' ),
6835
  'ownership_changed',
6836
- __fs( 'congrats' ) . '!'
6837
  );
6838
  } else {
6839
  // @todo Handle failed ownership change message.
@@ -6853,23 +6944,23 @@
6853
  switch ( $result->error->code ) {
6854
  case 'user_exist':
6855
  $this->_admin_notices->add(
6856
- __fs( 'user-exist-message' ) . ' ' .
6857
- sprintf( __fs( 'user-exist-message_ownership' ), '<b>' . $new_email . '</b>' ) .
6858
  sprintf(
6859
  '<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s &nbsp;&#10140;</button></a>',
6860
  $this->get_account_url( 'change_owner', array(
6861
  'state' => 'init',
6862
  'candidate_email' => $new_email
6863
  ) ),
6864
- __fs( 'change-ownership' )
6865
  ),
6866
- __fs( 'oops' ) . '...',
6867
  'error'
6868
  );
6869
  break;
6870
  }
6871
  } else {
6872
- $this->_admin_notices->add( __fs( 'email-updated-message' ) );
6873
  }
6874
 
6875
  return;
@@ -6881,12 +6972,12 @@
6881
 
6882
  if ( isset( $result->error ) ) {
6883
  $this->_admin_notices->add(
6884
- __fs( 'name-update-failed-message' ),
6885
- __fs( 'oops' ) . '...',
6886
  'error'
6887
  );
6888
  } else {
6889
- $this->_admin_notices->add( __fs( 'name-updated-message' ) );
6890
  }
6891
 
6892
  return;
@@ -6939,7 +7030,7 @@
6939
  $this->do_action( 'account_property_edit', 'site', $site_property, $site_property_value );
6940
 
6941
  $this->_admin_notices->add( sprintf(
6942
- __fs( 'x-updated' ),
6943
  '<b>' . str_replace( '_', ' ', $p ) . '</b>' ) );
6944
 
6945
  return;
@@ -7033,8 +7124,8 @@
7033
 
7034
  if ( ! $this->is_registered() && $this->is_org_repo_compliant() ) {
7035
  $this->_admin_notices->add(
7036
- sprintf( __fs( 'addons-info-external-message' ), '<b>' . $this->get_plugin_name() . '</b>' ),
7037
- __fs( 'heads-up' ),
7038
  'update-nag'
7039
  );
7040
  }
@@ -7098,15 +7189,15 @@
7098
  *
7099
  * @uses remove_all_actions()
7100
  */
7101
- function _hide_admin_notices() {
7102
  remove_all_actions( 'admin_notices' );
7103
  remove_all_actions( 'network_admin_notices' );
7104
  remove_all_actions( 'all_admin_notices' );
7105
  remove_all_actions( 'user_admin_notices' );
7106
  }
7107
 
7108
- function _clean_admin_content_section_hook() {
7109
- $this->_hide_admin_notices();
7110
 
7111
  // Hide footer.
7112
  echo '<style>#wpfooter { display: none !important; }</style>';
@@ -7118,8 +7209,8 @@
7118
  * @author Vova Feldman (@svovaf)
7119
  * @since 1.0.3
7120
  */
7121
- function _clean_admin_content_section() {
7122
- add_action( 'admin_head', array( &$this, '_clean_admin_content_section_hook' ) );
7123
  }
7124
 
7125
  /* CSS & JavaScript
@@ -7273,8 +7364,8 @@
7273
  $require_subscription = $paid_plan->is_require_subscription;
7274
  $upgrade_url = $this->get_trial_url();
7275
  $cc_string = $require_subscription ?
7276
- sprintf( __fs( 'no-commitment-for-x-days' ), $paid_plan->trial_period ) :
7277
- __fs( 'no-cc-required' ) . '!';
7278
 
7279
 
7280
  $total_paid_plans = count( $this->_plans ) - ( FS_Plan_Manager::instance()->has_free_plan( $this->_plans ) ? 1 : 0 );
@@ -7282,9 +7373,9 @@
7282
  if ( $total_paid_plans === $trial_plans_count ) {
7283
  // All paid plans have trials.
7284
  $message = sprintf(
7285
- __fs( 'hey' ) . '! ' . __fs( 'trial-x-promotion-message' ),
7286
  sprintf( '<b>%s</b>', $this->get_plugin_name() ),
7287
- strtolower( __fs( 'awesome' ) ),
7288
  $paid_plan->trial_period
7289
  );
7290
  } else {
@@ -7301,7 +7392,7 @@
7301
 
7302
  // Not all paid plans have trials.
7303
  $message = sprintf(
7304
- __fs( 'hey' ) . '! ' . __fs( 'trial-x-promotion-message' ),
7305
  sprintf( '<b>%s</b>', $this->get_plugin_name() ),
7306
  $plans_string,
7307
  $paid_plan->trial_period
@@ -7312,9 +7403,9 @@
7312
 
7313
  // Add start trial button.
7314
  $message .= ' ' . sprintf(
7315
- '<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s &nbsp;&#10140;</button></a>',
7316
  $upgrade_url,
7317
- __fs( 'start-free-trial' )
7318
  );
7319
 
7320
  $this->_admin_notices->add_sticky(
@@ -7411,7 +7502,7 @@
7411
  if ( $this->is_registered() ) {
7412
  if ( ! $this->is_paying() && $this->has_paid_plan() ) {
7413
  $this->add_plugin_action_link(
7414
- __fs( 'upgrade' ),
7415
  $this->get_upgrade_url(),
7416
  false,
7417
  20,
@@ -7421,7 +7512,7 @@
7421
 
7422
  if ( $this->_has_addons() ) {
7423
  $this->add_plugin_action_link(
7424
- __fs( 'add-ons' ),
7425
  $this->_get_admin_page_url( 'addons' ),
7426
  false,
7427
  WP_FS__DEFAULT_PRIORITY,
@@ -7644,6 +7735,24 @@
7644
 
7645
  #endregion ------------------------------------------------------------------
7646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7647
  #region Marketing ------------------------------------------------------------------
7648
 
7649
  /**
16
  *
17
  * @var string
18
  */
19
+ public $version = WP_FS__SDK_VERSION;
20
 
21
  #region Plugin Info
22
 
114
  */
115
  private $_has_addons;
116
 
117
+ /**
118
+ * @since 1.1.6
119
+ * @var string[]bool.
120
+ */
121
+ private $_permissions;
122
+
123
  /**
124
  * @var FS_Key_Value_Storage
125
  */
191
  */
192
  private $_admin_notices;
193
 
194
+ /**
195
+ * @since 1.1.6
196
+ *
197
+ * @var FS_Admin_Notice_Manager
198
+ */
199
+ private static $_global_admin_notices;
200
+
201
  /**
202
  * @var FS_Logger
203
  * @since 1.0.0
324
  * @param string $sdk_prev_version
325
  * @param string $sdk_version
326
  */
327
+ function _data_migration( $sdk_prev_version, $sdk_version ) {
328
+ if ( version_compare( $sdk_prev_version, '1.1.5', '<' ) &&
329
+ version_compare( $sdk_version, '1.1.5', '>=' )
330
  ) {
331
  // On version 1.1.5 merged connectivity and is_on data.
332
  if ( isset( $this->_storage->connectivity_test ) ) {
377
 
378
  $this->add_action( 'after_plans_sync', array( &$this, '_check_for_trial_plans' ) );
379
 
380
+ $this->add_action( 'sdk_version_update', array( &$this, '_data_migration' ), WP_FS__DEFAULT_PRIORITY, 2 );
381
  }
382
 
383
  /**
479
  function _get_uninstall_reasons( $user_type = 'long-term' ) {
480
  $reason_found_better_plugin = array(
481
  'id' => 2,
482
+ 'text' => __fs( 'reason-found-a-better-plugin', $this->_slug ),
483
  'input_type' => 'textfield',
484
+ 'input_placeholder' => __fs( 'placeholder-plugin-name', $this->_slug )
485
  );
486
 
487
  $reason_other = array(
488
  'id' => 7,
489
+ 'text' => __fs( 'reason-other', $this->_slug ),
490
  'input_type' => 'textfield',
491
  'input_placeholder' => ''
492
  );
494
  $long_term_user_reasons = array(
495
  array(
496
  'id' => 1,
497
+ 'text' => __fs( 'reason-no-longer-needed', $this->_slug ),
498
  'input_type' => '',
499
  'input_placeholder' => ''
500
  ),
501
  $reason_found_better_plugin,
502
  array(
503
  'id' => 3,
504
+ 'text' => __fs( 'reason-needed-for-a-short-period', $this->_slug ),
505
  'input_type' => '',
506
  'input_placeholder' => ''
507
  ),
508
  array(
509
  'id' => 4,
510
+ 'text' => __fs( 'reason-broke-my-site', $this->_slug ),
511
  'input_type' => '',
512
  'input_placeholder' => ''
513
  ),
514
  array(
515
  'id' => 5,
516
+ 'text' => __fs( 'reason-suddenly-stopped-working', $this->_slug ),
517
  'input_type' => '',
518
  'input_placeholder' => ''
519
  )
522
  if ( $this->is_paying() ) {
523
  $long_term_user_reasons[] = array(
524
  'id' => 6,
525
+ 'text' => __fs( 'reason-cant-pay-anymore', $this->_slug ),
526
  'input_type' => 'textfield',
527
+ 'input_placeholder' => __fs( 'placeholder-comfortable-price', $this->_slug )
528
  );
529
  }
530
 
535
  'non-registered-and-non-anonymous-short-term' => array(
536
  array(
537
  'id' => 8,
538
+ 'text' => __fs( 'reason-didnt-work', $this->_slug ),
539
  'input_type' => '',
540
  'input_placeholder' => ''
541
  ),
542
  array(
543
  'id' => 9,
544
+ 'text' => __fs( 'reason-dont-like-to-share-my-information', $this->_slug ),
545
  'input_type' => '',
546
  'input_placeholder' => ''
547
  ),
551
  'short-term' => array(
552
  array(
553
  'id' => 10,
554
+ 'text' => __fs( 'reason-couldnt-make-it-work', $this->_slug ),
555
  'input_type' => '',
556
  'input_placeholder' => ''
557
  ),
558
  $reason_found_better_plugin,
559
  array(
560
  'id' => 11,
561
+ 'text' => __fs( 'reason-great-but-need-specific-feature', $this->_slug ),
562
  'input_type' => 'textarea',
563
+ 'input_placeholder' => __fs( 'placeholder-feature', $this->_slug )
564
  ),
565
  array(
566
  'id' => 12,
567
+ 'text' => __fs( 'reason-not-working', $this->_slug ),
568
  'input_type' => 'textarea',
569
+ 'input_placeholder' => __fs( 'placeholder-share-what-didnt-work', $this->_slug )
570
  ),
571
  array(
572
  'id' => 13,
573
+ 'text' => __fs( 'reason-not-what-i-was-looking-for', $this->_slug ),
574
  'input_type' => 'textarea',
575
+ 'input_placeholder' => __fs( 'placeholder-what-youve-been-looking-for', $this->_slug )
576
  ),
577
  array(
578
  'id' => 14,
579
+ 'text' => __fs( 'reason-didnt-work-as-expected', $this->_slug ),
580
  'input_type' => 'textarea',
581
+ 'input_placeholder' => __fs( 'placeholder-what-did-you-expect', $this->_slug )
582
  ),
583
  $reason_other
584
  )
621
  * @since 1.0.6
622
  *
623
  * @return string
624
+ *
625
+ * @uses fs_find_caller_plugin_file
626
  */
627
  private function _find_caller_plugin_file() {
 
 
 
628
  // Try to load the cached value of the file path.
629
  if ( isset( $this->_storage->plugin_main_file ) ) {
630
  if ( file_exists( $this->_storage->plugin_main_file->path ) ) {
632
  }
633
  }
634
 
635
+ $plugin_file = fs_find_caller_plugin_file();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
 
637
  $this->_storage->plugin_main_file = (object) array(
638
  'path' => fs_normalize_path( $plugin_file ),
804
 
805
  self::$_accounts = FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
806
 
807
+ self::$_global_admin_notices = FS_Admin_Notice_Manager::instance( 'global' );
808
+
809
  // Configure which Freemius powered plugins should be auto updated.
810
  // add_filter( 'auto_update_plugin', '_include_plugins_in_auto_update', 10, 2 );
811
 
812
+ add_action( 'admin_menu', array( 'Freemius', 'add_debug_page' ) );
 
 
813
 
814
  self::$_statics_loaded = true;
815
  }
821
  * @since 1.0.8
822
  */
823
  static function add_debug_page() {
824
+ if ( ! current_user_can( 'activate_plugins' ) ) {
825
+ return;
826
+ }
827
+
828
  self::$_static_logger->entrance();
829
 
830
+ $title = sprintf( '%s [v.%s]', __fs( 'freemius-debug' ), WP_FS__SDK_VERSION );
831
+
832
+ if ( WP_FS__DEV_MODE ) {
833
+ // Add top-level debug menu item.
834
+ $hook = add_object_page(
835
+ $title,
836
+ $title,
837
+ 'manage_options',
838
+ 'freemius',
839
+ array( 'Freemius', '_debug_page_render' )
840
+ );
841
+ } else {
842
+ // Add hidden debug page.
843
+ $hook = add_submenu_page(
844
+ null,
845
+ $title,
846
+ $title,
847
+ 'manage_options',
848
+ 'freemius',
849
+ array( 'Freemius', '_debug_page_render' )
850
+ );
851
+ }
852
 
853
  add_action( "load-$hook", array( 'Freemius', '_debug_page_actions' ) );
854
  }
858
  * @since 1.0.8
859
  */
860
  static function _debug_page_actions() {
861
+ self::_clean_admin_content_section();
862
+
863
  if ( fs_request_is_action( 'delete_all_accounts' ) ) {
864
  check_admin_referer( 'delete_all_accounts' );
865
 
900
  /**
901
  * Check if Freemius should be turned on for the current plugin install.
902
  *
903
+ * Note:
904
+ * $this->_is_on is updated in has_api_connectivity()
905
+ *
906
  * @author Vova Feldman (@svovaf)
907
  * @since 1.0.9
908
  *
909
  * @return bool
910
  */
911
+ function is_on() {
912
  self::$_static_logger->entrance();
913
 
914
  if ( isset( $this->_is_on ) ) {
919
  if ( $this->is_registered() || $this->is_pending_activation() ) {
920
  $this->_is_on = true;
921
 
922
+ return true;
923
  }
924
+
925
+ return false;
926
  }
927
 
928
  /**
935
  *
936
  * @return bool
937
  */
938
+ function has_api_connectivity( $flush = false ) {
939
+ if ( ! $flush && isset( $this->_has_api_connection ) ) {
940
  return $this->_has_api_connection;
941
  }
942
 
949
  unset( $this->_storage->connectivity_test );
950
  }
951
 
952
+ if ( isset( $this->_storage->connectivity_test ) ) {
953
+ if ( ! WP_FS__IS_HTTP_REQUEST ||
954
+ ( $_SERVER['HTTP_HOST'] == $this->_storage->connectivity_test['host'] &&
955
+ WP_FS__REMOTE_ADDR == $this->_storage->connectivity_test['server_ip'] )
956
  ) {
957
  if ( ( $this->_storage->connectivity_test['is_connected'] &&
958
  $this->_storage->connectivity_test['is_active'] ) ||
959
+ ( ! $flush &&
960
+ $version == $this->_storage->connectivity_test['version'] )
961
  ) {
962
  $this->_has_api_connection = $this->_storage->connectivity_test['is_connected'];
963
+ $this->_is_on = $this->_storage->connectivity_test['is_active'] || ( WP_FS__DEV_MODE && $this->_has_api_connection );
964
 
965
  return $this->_has_api_connection;
966
  }
967
  }
968
  }
969
 
970
+ $is_update = $this->apply_filters( 'is_plugin_update', $this->is_plugin_update() );
971
 
972
  if ( WP_FS__SIMULATE_NO_API_CONNECTIVITY ) {
973
  $is_connected = false;
995
  $this->_storage->connectivity_test = array(
996
  'is_connected' => $is_connected,
997
  'host' => $_SERVER['HTTP_HOST'],
998
+ 'server_ip' => WP_FS__REMOTE_ADDR,
999
  'is_active' => $is_active,
1000
  'timestamp' => WP_FS__SCRIPT_START_TIME,
1001
  // Last version with connectivity attempt.
1003
  );
1004
 
1005
  $this->_has_api_connection = $is_connected;
1006
+ $this->_is_on = $is_active || ( WP_FS__DEV_MODE && $is_connected );
1007
 
1008
  return $this->_has_api_connection;
1009
  }
1062
  switch ( $api_result->error->code ) {
1063
  case 'curl_missing':
1064
  $message = sprintf(
1065
+ __fs( 'x-requires-access-to-api', $this->_slug ) . ' ' .
1066
+ __fs( 'curl-missing-message', $this->_slug ) . ' ' .
1067
  ' %s',
1068
  '<b>' . $this->get_plugin_name() . '</b>',
1069
  sprintf(
1070
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1071
  sprintf(
1072
  '<a class="fs-resolve" data-type="curl" href="#"><b>%s</b></a>%s',
1073
+ __fs( 'curl-missing-no-clue-title', $this->_slug ),
1074
  ' - ' . sprintf(
1075
+ __fs( 'curl-missing-no-clue-desc', $this->_slug ),
1076
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1077
  )
1078
  ),
1079
  sprintf(
1080
  '<b>%s</b> - %s',
1081
+ __fs( 'sysadmin-title', $this->_slug ),
1082
+ __fs( 'curl-missing-sysadmin-desc', $this->_slug )
1083
  ),
1084
  sprintf(
1085
  '<a href="%s"><b>%s</b></a>%s',
1086
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1087
+ __fs( 'deactivate-plugin-title', $this->_slug ),
1088
+ ' - ' . __fs( 'deactivate-plugin-desc', 'freemius', $this->_slug )
1089
  )
1090
  )
1091
  );
1092
  break;
1093
  case 'cloudflare_ddos_protection':
1094
  $message = sprintf(
1095
+ __fs( 'x-requires-access-to-api', $this->_slug ) . ' ' .
1096
+ __fs( 'cloudflare-blocks-connection-message', $this->_slug ) . ' ' .
1097
+ __fs( 'happy-to-resolve-issue-asap', $this->_slug ) .
1098
  ' %s',
1099
  '<b>' . $this->get_plugin_name() . '</b>',
1100
  sprintf(
1101
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1102
  sprintf(
1103
  '<a class="fs-resolve" data-type="cloudflare" href="#"><b>%s</b></a>%s',
1104
+ __fs( 'fix-issue-title', $this->_slug ),
1105
  ' - ' . sprintf(
1106
+ __fs( 'fix-issue-desc', $this->_slug ),
1107
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1108
  )
1109
  ),
1110
  sprintf(
1111
  '<a href="%s" target="_blank"><b>%s</b></a>%s',
1112
  sprintf( 'https://wordpress.org/plugins/%s/download/', $this->_slug ),
1113
+ __fs( 'install-previous-title', $this->_slug ),
1114
+ ' - ' . __fs( 'install-previous-desc', $this->_slug )
1115
  ),
1116
  sprintf(
1117
  '<a href="%s"><b>%s</b></a>%s',
1118
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1119
+ __fs( 'deactivate-plugin-title', $this->_slug ),
1120
+ ' - ' . __fs( 'deactivate-plugin-desc', $this->_slug )
1121
  )
1122
  )
1123
  );
1124
  break;
1125
  case 'squid_cache_block':
1126
  $message = sprintf(
1127
+ __fs( 'x-requires-access-to-api', $this->_slug ) . ' ' .
1128
+ __fs( 'squid-blocks-connection-message', $this->_slug ) .
1129
  ' %s',
1130
  '<b>' . $this->get_plugin_name() . '</b>',
1131
  sprintf(
1132
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1133
  sprintf(
1134
  '<a class="fs-resolve" data-type="squid" href="#"><b>%s</b></a>%s',
1135
+ __fs( 'squid-no-clue-title', $this->_slug ),
1136
  ' - ' . sprintf(
1137
+ __fs( 'squid-no-clue-desc', $this->_slug ),
1138
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1139
  )
1140
  ),
1141
  sprintf(
1142
  '<b>%s</b> - %s',
1143
+ __fs( 'sysadmin-title', $this->_slug ),
1144
  sprintf(
1145
+ __fs( 'squid-sysadmin-desc', $this->_slug ),
1146
  // We use a filter since the plugin might require additional API connectivity.
1147
  '<b>' . implode( ', ', $this->apply_filters( 'api_domains', array( 'api.freemius.com' ) ) ) . '</b>' )
1148
  ),
1149
  sprintf(
1150
  '<a href="%s"><b>%s</b></a>%s',
1151
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1152
+ __fs( 'deactivate-plugin-title', $this->_slug ),
1153
+ ' - ' . __fs( 'deactivate-plugin-desc', $this->_slug )
1154
  )
1155
  )
1156
  );
1157
  break;
1158
  default:
1159
+ $message = __fs( 'connectivity-test-fails-message', $this->_slug );
1160
  break;
1161
  }
1162
  }
1163
 
1164
  if ( false === $message ) {
1165
  $message = sprintf(
1166
+ __fs( 'x-requires-access-to-api', $this->_slug ) . ' ' .
1167
+ __fs( 'connectivity-test-fails-message', $this->_slug ) . ' ' .
1168
+ __fs( 'happy-to-resolve-issue-asap', $this->_slug ) .
1169
  ' %s',
1170
  '<b>' . $this->get_plugin_name() . '</b>',
1171
  sprintf(
1172
  '<ol id="fs_firewall_issue_options"><li>%s</li><li>%s</li><li>%s</li></ol>',
1173
  sprintf(
1174
  '<a class="fs-resolve" data-type="general" href="#"><b>%s</b></a>%s',
1175
+ __fs( 'fix-issue-title', $this->_slug ),
1176
  ' - ' . sprintf(
1177
+ __fs( 'fix-issue-desc', $this->_slug ),
1178
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1179
  )
1180
  ),
1181
  sprintf(
1182
  '<a href="%s" target="_blank"><b>%s</b></a>%s',
1183
  sprintf( 'https://wordpress.org/plugins/%s/download/', $this->_slug ),
1184
+ __fs( 'install-previous-title', $this->_slug ),
1185
+ ' - ' . __fs( 'install-previous-desc', $this->_slug )
1186
  ),
1187
  sprintf(
1188
  '<a href="%s"><b>%s</b></a>%s',
1189
  wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $this->_plugin_basename . '&amp;plugin_status=' . 'all' . '&amp;paged=' . '1' . '&amp;s=' . '', 'deactivate-plugin_' . $this->_plugin_basename ),
1190
+ __fs( 'deactivate-plugin-title', $this->_slug ),
1191
+ ' - ' . __fs( 'deactivate-plugin-desc', $this->_slug )
1192
  )
1193
  )
1194
  );
1197
  $this->_admin_notices->add_sticky(
1198
  $message,
1199
  'failed_connect_api',
1200
+ __fs( 'oops', $this->_slug ) . '...',
1201
  'error'
1202
  );
1203
  }
1285
 
1286
  $this->_admin_notices->add_sticky(
1287
  sprintf(
1288
+ __fs( 'fix-request-sent-message', $this->_slug ),
1289
  '<a href="mailto:' . $admin_email . '">' . $admin_email . '</a>'
1290
  ),
1291
  'server_details_sent'
1400
  );
1401
  }
1402
 
1403
+ $server_ip = WP_FS__REMOTE_ADDR;
1404
+
1405
  // Generate the default email sections.
1406
  $sections = array(
1407
  'sdk' => array(
1428
  ),
1429
  'server_addr' => array(
1430
  'SERVER_ADDR',
1431
+ '<a href="http://www.projecthoneypot.org/ip_' . $server_ip . '">' . $server_ip . '</a>'
1432
  )
1433
  )
1434
  ),
1480
  ) );
1481
  }
1482
 
1483
+ /**
1484
+ * @param string[] $options
1485
+ * @param string $key
1486
+ * @param mixed $default
1487
+ *
1488
+ * @return bool
1489
+ */
1490
  private function _get_option( &$options, $key, $default = false ) {
1491
  return ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
1492
  }
1572
  $this->_has_paid_plans = $this->_get_bool_option( $plugin_info, 'has_paid_plans', true );
1573
  $this->_is_org_compliant = $this->_get_bool_option( $plugin_info, 'is_org_compliant', true );
1574
  $this->_enable_anonymous = $this->_get_bool_option( $plugin_info, 'enable_anonymous', true );
1575
+ $this->_permissions = $this->_get_option( $plugin_info, 'permissions', array() );
1576
 
1577
  if ( ! $this->is_registered() ) {
1578
+ if ( ! WP_FS__IS_HTTP_REQUEST ) {
1579
+ /**
1580
+ * If not registered and executed without HTTP context (e.g. CLI, Cronjob),
1581
+ * then don't start Freemius.
1582
+ *
1583
+ * @author Vova Feldman (@svovaf)
1584
+ * @since 1.1.6.3
1585
+ *
1586
+ * @link https://wordpress.org/support/topic/errors-in-the-freemius-class-when-running-in-wordpress-in-cli
1587
+ */
1588
+ return;
1589
+ }
1590
+
1591
  if ( ! $this->has_api_connectivity() ) {
1592
  if ( is_admin() && $this->_admin_notices->has_sticky( 'failed_connect_api' ) ) {
1593
  if ( ! $this->_enable_anonymous ) {
1643
  if ( ! $this->is_parent_plugin_installed() ) {
1644
  $this->_admin_notices->add(
1645
  ( is_string( $parent_name ) ?
1646
+ sprintf( __fs( 'addon-cannot-run-without-x', $this->_slug ), $this->get_plugin_name(), $parent_name ) :
1647
+ sprintf( __fs( 'addon-x-cannot-run-without-parent', $this->_slug ), $this->get_plugin_name() )
1648
  ),
1649
+ __fs( 'oops', $this->_slug ) . '...',
1650
  'error'
1651
  );
1652
 
1679
  add_action( 'install_plugins_pre_plugin-information', 'fs_install_plugin_information' );
1680
 
1681
  // Override request for plugin information for Add-ons.
1682
+ add_filter( 'fs_plugins_api', array(
1683
+ &$this,
1684
+ '_get_addon_info_filter'
1685
+ ), WP_FS__DEFAULT_PRIORITY, 3 );
 
1686
  }
1687
  }
1688
 
1689
+ if ( $this->is_premium() ) {
1690
+ new FS_Plugin_Updater( $this );
1691
+ }
1692
+
1693
  // if ( $this->is_registered() ||
1694
  // $this->is_anonymous() ||
1695
  // $this->is_pending_activation()
1757
  ) );
1758
 
1759
  $this->_admin_notices->add_sticky(
1760
+ __fs( 'premium-activated-message', $this->_slug ),
1761
  'premium_activated',
1762
+ __fs( 'woot', $this->_slug ) . '!'
1763
  );
1764
  } else {
1765
  // Activated free code (after had the premium before).
1768
  if ( $this->is_paying() && ! $this->is_premium() ) {
1769
  $this->_admin_notices->add_sticky(
1770
  sprintf(
1771
+ __fs( 'you-have-x-license', $this->_slug ),
1772
  $this->_site->plan->title
1773
  ) . ' ' . $this->_get_latest_download_link( sprintf(
1774
+ __fs( 'download-x-version-now', $this->_slug ),
1775
  $this->_site->plan->title
1776
  ) ),
1777
  'plan_upgraded',
1778
+ __fs( 'yee-haw', $this->_slug ) . '!'
1779
  );
1780
  }
1781
  }
1855
  }
1856
 
1857
  if ( ! empty( $selected_addon->info->screenshots ) ) {
1858
+ $view_vars = array(
1859
+ 'screenshots' => $selected_addon->info->screenshots,
1860
+ 'plugin' => $selected_addon,
1861
+ );
1862
  $data->sections['screenshots'] = fs_get_template( '/plugin-info/screenshots.php', $view_vars );
1863
  }
1864
 
1916
  $data->plans = $plans;
1917
 
1918
  if ( $has_features ) {
1919
+ $view_vars = array(
1920
+ 'plans' => $plans,
1921
+ 'plugin' => $selected_addon,
1922
+ );
1923
  $data->sections['features'] = fs_get_template( '/plugin-info/features.php', $view_vars );
1924
  }
1925
  }
2159
  return false;
2160
  }
2161
 
2162
+ // Check if API is not down.
2163
+ if ( FS_Api::is_temporary_down() ) {
2164
+ return false;
2165
+ }
2166
+
2167
  $sync_timestamp = $this->_storage->get( 'sync_timestamp' );
2168
 
2169
  if ( ! is_numeric( $sync_timestamp ) || $sync_timestamp >= time() ) {
2180
  // Initiate background plan sync.
2181
  $this->_sync_license( true );
2182
 
2183
+ if ( $this->is_paying() ) {
2184
+ // Check for plugin updates.
2185
+ $this->_check_updates( true );
2186
+ }
2187
  }
2188
 
2189
  if ( ! $this->is_addon() ) {
2219
 
2220
  $this->_admin_notices->add_sticky(
2221
  sprintf(
2222
+ __fs( 'pending-activation-message', $this->_slug ),
2223
  '<b>' . $this->get_plugin_name() . '</b>',
2224
  '<b>' . $email . '</b>'
2225
  ),
2273
  // Show notice for new plugin installations.
2274
  $this->_admin_notices->add(
2275
  sprintf(
2276
+ __fs( 'you-are-step-away', $this->_slug ),
2277
  sprintf( '<b><a href="%s">%s</a></b>',
2278
  $this->get_activation_url(),
2279
+ sprintf( __fs( 'activate-x-now', $this->_slug ), $this->get_plugin_name() )
2280
  )
2281
  ),
2282
  '',
2289
  // Show notice for new plugin installations.
2290
  $this->_admin_notices->add_sticky(
2291
  sprintf(
2292
+ __fs( 'few-plugin-tweaks', $this->_slug ),
2293
  sprintf( '<b><a href="%s">%s</a></b>',
2294
  $this->get_activation_url(),
2295
+ sprintf( __fs( 'optin-x-now', $this->_slug ), $this->get_plugin_name() )
2296
  )
2297
  ),
2298
  'connect_account',
2300
  'update-nag'
2301
  );
2302
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2303
  }
2304
  }
2305
  }
2323
 
2324
  fs_enqueue_local_style( 'fs_connect', '/admin/connect.css' );
2325
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2326
  /**
2327
  * Return current page's URL.
2328
  *
2424
  }
2425
 
2426
  /**
2427
+ * Check if Freemius was added on new plugin installation.
2428
+ *
2429
  * @author Vova Feldman (@svovaf)
2430
  * @since 1.1.5
2431
  *
2432
  * @return bool
2433
  */
2434
+ function is_plugin_new_install() {
2435
+ return isset( $this->_storage->is_plugin_new_install ) &&
 
2436
  $this->_storage->is_plugin_new_install;
2437
  }
2438
 
2466
  deactivate_plugins( $this->_free_plugin_basename );
2467
 
2468
  $this->_admin_notices->add(
2469
+ sprintf( __fs( 'successful-version-upgrade-message', $this->_slug ), sprintf( '<b>%s</b>', $this->_plugin->title ) ),
2470
+ __fs( 'woot', $this->_slug ) . '!'
2471
  );
2472
  }
2473
  } else if ( $this->is_anonymous() ) {
2501
  $this->_storage->is_plugin_new_install = empty( $this->_storage->plugin_last_version );
2502
  }
2503
 
2504
+ if ( $this->has_api_connectivity( true ) ) {
2505
  // Store hint that the plugin was just activated to enable auto-redirection to settings.
2506
  add_option( "fs_{$this->_slug}_activated", true );
2507
  }
2566
  }
2567
 
2568
  $this->_admin_notices->clear_all_sticky();
2569
+ if ( isset( $this->_storage->sticky_optin_added ) ) {
2570
+ unset( $this->_storage->sticky_optin_added );
2571
+ }
2572
 
2573
  if ( ! $this->has_api_connectivity() ) {
2574
  // Reset connectivity test cache.
2575
  unset( $this->_storage->connectivity_test );
2576
  }
2577
 
2578
+ if ( ! isset( $this->_storage->is_plugin_new_install ) ) {
2579
  // Remember that plugin was already installed.
2580
  $this->_storage->is_plugin_new_install = false;
2581
  }
2589
 
2590
  // Clear API cache on deactivation.
2591
  FS_Api::clear_cache();
2592
+
2593
+ $this->remove_sdk_reference();
2594
+ }
2595
+
2596
+ /**
2597
+ * @author Vova Feldman (@svovaf)
2598
+ * @since 1.1.6
2599
+ */
2600
+ private function remove_sdk_reference() {
2601
+ global $fs_active_plugins;
2602
+
2603
+ foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
2604
+ if ( $this->_plugin_basename == $data->plugin_path ) {
2605
+ unset( $fs_active_plugins->plugins[ $sdk_path ] );
2606
+ break;
2607
+ }
2608
+ }
2609
+
2610
+ fs_fallback_to_newest_active_sdk();
2611
  }
2612
 
2613
  /**
2624
  'timestamp' => WP_FS__SCRIPT_START_TIME,
2625
  'version' => $this->get_plugin_version(),
2626
  );
2627
+
2628
+ // Update anonymous mode cache.
2629
+ $this->_is_anonymous = $is_anonymous;
2630
  }
2631
 
2632
  /**
2666
  private function update_plugin_version_event() {
2667
  $this->_logger->entrance( 'slug = ' . $this->_slug );
2668
 
 
 
2669
  // Send update event.
2670
  $site = $this->send_install_update( array(), true );
2671
 
2672
  if ( false !== $site && ! $this->is_api_error( $site ) ) {
2673
  $this->_site = new FS_Site( $site );
2674
  $this->_site->plan = $this->_get_plan_by_id( $site->plan_id );
 
2675
  }
2676
+
2677
+ $this->_site->version = $this->get_plugin_version();
2678
+ $this->_store_site( true );
2679
  }
2680
 
2681
  /**
3280
  return $addons[ $this->_plugin->id ];
3281
  }
3282
 
3283
+ /**
3284
+ * Check if user has any
3285
+ *
3286
+ * @author Vova Feldman (@svovaf)
3287
+ * @since 1.1.6
3288
+ *
3289
+ * @return bool
3290
+ */
3291
+ function has_account_addons() {
3292
+ $addons = $this->get_account_addons();
3293
+
3294
+ return is_array( $addons ) && ( 0 < count( $addons ) );
3295
+ }
3296
+
3297
+
3298
  /**
3299
  * Get add-on by ID (from local data).
3300
  *
4205
  return;
4206
  }
4207
 
4208
+ self::_clean_admin_content_section();
4209
 
4210
  if ( fs_request_is_action( 'activate' ) && fs_request_is_post() ) {
4211
  // check_admin_referer( 'activate_' . $this->_plugin->public_key );
4384
  function setup_account( FS_User $user, FS_Site $site, $redirect = true ) {
4385
  $this->_user = $user;
4386
  $this->_site = $site;
4387
+
4388
+ $this->_sync_plans();
4389
+
4390
  $this->_enrich_site_plan( false );
4391
 
4392
  $this->_set_account( $user, $site );
 
4393
 
4394
  if ( $this->is_trial() ) {
4395
  // Store trial plan information.
4411
 
4412
  if ( ! $this->is_paying() ) {
4413
  $this->_admin_notices->add_sticky(
4414
+ sprintf( __fs( 'plugin-x-activation-message', $this->_slug ), '<b>' . $this->get_plugin_name() . '</b>' ),
4415
  'activation_complete'
4416
  );
4417
  }
4420
  if ( $this->is_paying() && ! $this->is_premium() ) {
4421
  $this->_admin_notices->add_sticky(
4422
  sprintf(
4423
+ __fs( 'activation-with-plan-x-message', $this->_slug ),
4424
  $this->_site->plan->title
4425
  ) . ' ' . $this->_get_latest_download_link( sprintf(
4426
+ __fs( 'download-latest-x-version', $this->_slug ),
4427
  $this->_site->plan->title
4428
  ) ),
4429
  'plan_upgraded',
4430
+ __fs( 'yee-haw', $this->_slug ) . '!'
4431
  );
4432
  }
4433
 
4468
  * @since 1.0.7
4469
  */
4470
  function _install_with_new_user() {
4471
+ $this->_logger->entrance();
4472
+
4473
  if ( $this->is_registered() ) {
4474
  return;
4475
  }
4522
  * @since 1.0.7
4523
  */
4524
  function _install_with_current_user() {
4525
+ $this->_logger->entrance();
4526
+
4527
  if ( $this->is_registered() ) {
4528
  return;
4529
  }
4553
 
4554
  if ( isset( $install->error ) ) {
4555
  $this->_admin_notices->add(
4556
+ sprintf( __fs( 'could-not-activate-x', $this->_slug ), $this->get_plugin_name() ) . ' ' .
4557
+ __fs( 'contact-us-with-error-message', $this->_slug ) . ' ' . '<b>' . $install->error->message . '</b>',
4558
+ __fs( 'oops', $this->_slug ) . '...',
4559
  'error'
4560
  );
4561
 
4598
 
4599
  if ( isset( $addon_install->error ) ) {
4600
  $this->_admin_notices->add(
4601
+ sprintf( __fs( 'could-not-activate-x', $this->_slug ), $this->get_plugin_name() ) . ' ' .
4602
+ __fs( 'contact-us-with-error-message', $this->_slug ) . ' ' . '<b>' . $addon_install->error->message . '</b>',
4603
+ __fs( 'oops', $this->_slug ) . '...',
4604
  'error'
4605
  );
4606
 
4778
 
4779
  if ( $this->_menu->is_activation_page() ) {
4780
  // Clean admin page from distracting content.
4781
+ self::_clean_admin_content_section();
4782
  }
4783
 
4784
  if ( false !== $hook ) {
4818
  if ( $this->is_registered() ) {
4819
  // Add user account page.
4820
  $this->add_submenu_item(
4821
+ __fs( 'account', $this->_slug ),
4822
  array( &$this, '_account_page_render' ),
4823
+ $this->get_plugin_name() . ' &ndash; ' . __fs( 'account', $this->_slug ),
4824
  'manage_options',
4825
  'account',
4826
  array( &$this, '_account_page_load' ),
4831
 
4832
  // Add contact page.
4833
  $this->add_submenu_item(
4834
+ __fs( 'contact-us', $this->_slug ),
4835
  array( &$this, '_contact_page_render' ),
4836
+ $this->get_plugin_name() . ' &ndash; ' . __fs( 'contact-us', $this->_slug ),
4837
  'manage_options',
4838
  'contact',
4839
+ 'Freemius::_clean_admin_content_section',
4840
  WP_FS__DEFAULT_PRIORITY,
4841
  $this->_menu->is_submenu_item_visible( 'contact' )
4842
  );
4843
 
4844
  if ( $this->_has_addons() ) {
4845
  $this->add_submenu_item(
4846
+ __fs( 'add-ons', $this->_slug ),
4847
  array( &$this, '_addons_page_render' ),
4848
+ $this->get_plugin_name() . ' &ndash; ' . __fs( 'add-ons', $this->_slug ),
4849
  'manage_options',
4850
  'addons',
4851
  array( &$this, '_addons_page_load' ),
4854
  );
4855
  }
4856
 
4857
+ $show_pricing = ( $this->has_paid_plan() && $this->_menu->is_submenu_item_visible( 'pricing' ) );
4858
+ // If user don't have paid plans, add pricing page
4859
+ // to support add-ons checkout but don't add the submenu item.
4860
+ // || (isset( $_GET['page'] ) && $this->_menu->get_slug( 'pricing' ) == $_GET['page']);
4861
+
4862
  // Add upgrade/pricing page.
4863
  $this->add_submenu_item(
4864
+ ( $this->is_paying() ? __fs( 'pricing', $this->_slug ) : __fs( 'upgrade', $this->_slug ) . '&nbsp;&nbsp;&#x27a4;' ),
4865
  array( &$this, '_pricing_page_render' ),
4866
+ $this->get_plugin_name() . ' &ndash; ' . __fs( 'pricing', $this->_slug ),
4867
  'manage_options',
4868
  'pricing',
4869
+ 'Freemius::_clean_admin_content_section',
4870
  WP_FS__LOWEST_PRIORITY,
4871
+ $show_pricing
 
 
4872
  );
4873
  }
4874
  }
4985
  if ( $this->is_registered() ) {
4986
  if ( $this->_menu->is_submenu_item_visible( 'support' ) ) {
4987
  $this->add_submenu_link_item(
4988
+ $this->apply_filters( 'support_forum_submenu', __fs( 'support-forum', $this->_slug ) ),
4989
+ $this->apply_filters( 'support_forum_url', 'https://wordpress.org/support/plugin/' . $this->_slug ),
4990
  'wp-support-forum',
4991
  'read',
4992
  50
5168
  $this->_logger->entrance( $tag );
5169
 
5170
  $args = func_get_args();
5171
+ array_unshift($args, $this->_slug);
5172
 
5173
+ return call_user_func_array( 'fs_apply_filter', $args);
 
 
 
5174
  }
5175
 
5176
  /**
5200
  *
5201
  * @param string $tag
5202
  * @param callable|bool $function_to_check Optional. The callback to check for. Default false.
5203
+ *
5204
+ * @return false|int
5205
+ *
5206
+ * @uses has_filter()
5207
  */
5208
  function has_filter( $tag, $function_to_check = false ) {
5209
  $this->_logger->entrance( $tag );
5211
  return has_filter( 'fs_' . $tag . '_' . $this->_slug, $function_to_check );
5212
  }
5213
 
5214
+ /**
5215
+ * Override default i18n text phrases.
5216
+ *
5217
+ * @author Vova Feldman (@svovaf)
5218
+ * @since 1.1.6
5219
+ *
5220
+ * @param string[] string $key_value
5221
+ *
5222
+ * @uses fs_override_i18n()
5223
+ */
5224
+ function override_i18n( $key_value ) {
5225
+ fs_override_i18n( $key_value, $this->_slug );
5226
+ }
5227
+
5228
  /* Account Page
5229
  ------------------------------------------------------------------------------------------------------------------*/
5230
  /**
5435
  $this->_user->last = $user->last;
5436
  $this->_user->email = $user->email;
5437
 
5438
+ $is_menu_item_account_visible = $this->_menu->is_submenu_item_visible( 'account' );
5439
+
5440
+ if ( $user->is_verified &&
5441
+ ( ! isset( $this->_user->is_verified ) || false === $this->_user->is_verified )
5442
+ ) {
5443
+ $this->_user->is_verified = true;
5444
 
5445
  $this->do_action( 'account_email_verified', $user->email );
5446
 
5447
  $this->_admin_notices->add(
5448
+ __fs( 'email-verified-message', $this->_slug ),
5449
+ __fs( 'right-on', $this->_slug ) . '!',
5450
+ 'success',
5451
+ // Make admin sticky if account menu item is invisible,
5452
+ // since the page will be auto redirected to the plugin's
5453
+ // main settings page, and the non-sticky message
5454
+ // will disappear.
5455
+ ! $is_menu_item_account_visible,
5456
+ false,
5457
+ 'email_verified'
5458
  );
5459
  }
5460
 
5462
  $this->_store_user();
5463
 
5464
  $this->do_action( 'after_account_user_sync', $user );
5465
+
5466
+ /**
5467
+ * If account menu item is hidden, redirect to plugin's main settings page.
5468
+ *
5469
+ * @author Vova Feldman (@svovaf)
5470
+ * @since 1.1.6
5471
+ *
5472
+ * @link https://github.com/Freemius/wordpress-sdk/issues/6
5473
+ */
5474
+ if ( ! $is_menu_item_account_visible ) {
5475
+ if ( fs_redirect( $this->_get_admin_page_url() ) ) {
5476
+ exit();
5477
+ }
5478
+ }
5479
  }
5480
  }
5481
 
5849
  $this->_admin_notices->add_sticky(
5850
  FS_Plan_Manager::instance()->has_free_plan( $plans ) ?
5851
  sprintf(
5852
+ __fs( 'addon-successfully-upgraded-message', $this->_slug ),
5853
  $addon->title
5854
  ) . ' ' . $this->_get_latest_download_link(
5855
+ __fs( 'download-latest-version', $this->_slug ),
5856
  $addon_id
5857
  )
5858
  :
5859
  sprintf(
5860
+ __fs( 'addon-successfully-purchased-message', $this->_slug ),
5861
  $addon->title
5862
  ) . ' ' . $this->_get_latest_download_link(
5863
+ __fs( 'download-latest-version', $this->_slug ),
5864
  $addon_id
5865
  ),
5866
  'addon_plan_upgraded_' . $addon->slug,
5867
+ __fs( 'yee-haw', $this->_slug ) . '!'
5868
  );
5869
  }
5870
  }
5890
  $plan_change = 'none';
5891
 
5892
  if ( $this->is_api_error( $site ) ) {
5893
+ // Show API messages only if not background sync or if paying customer.
5894
+ if ( ! $background || $this->is_paying() ) {
5895
+ // Try to ping API to see if not blocked.
5896
+ if ( ! FS_Api::test() ) {
5897
+ /**
5898
+ * Failed to ping API - blocked!
5899
+ *
5900
+ * @author Vova Feldman (@svovaf)
5901
+ * @since 1.1.6 Only show message related to one of the Freemius powered plugins. Once it will be resolved it will fix the issue for all plugins anyways. There's no point to scare users with multiple error messages.
5902
+ */
5903
+ $api = $this->get_api_site_scope();
5904
+
5905
+ if ( ! self::$_global_admin_notices->has_sticky( 'api_blocked' ) ) {
5906
+ self::$_global_admin_notices->add(
5907
+ sprintf(
5908
+ __fs( 'server-blocking-access', $this->_slug ),
5909
+ $this->get_plugin_name(),
5910
+ '<a href="' . $api->get_url() . '" target="_blank">' . $api->get_url() . '</a>'
5911
+ ) . '<br> ' . __fs( 'server-error-message', $this->_slug ) . var_export( $site->error, true ),
5912
+ __fs( 'oops', $this->_slug ) . '...',
5913
+ 'error',
5914
+ $background,
5915
+ false,
5916
+ 'api_blocked'
5917
+ );
5918
+ }
5919
+ } else {
5920
+ // Authentication params are broken.
5921
+ $this->_admin_notices->add(
5922
+ __fs( 'wrong-authentication-param-message', $this->_slug ),
5923
+ __fs( 'oops', $this->_slug ) . '...',
5924
+ 'error'
5925
+ );
5926
+ }
5927
  }
5928
  } else {
5929
+ // Remove sticky API connectivity message.
5930
+ self::$_global_admin_notices->remove_sticky('api_blocked');
5931
+
5932
  $site = new FS_Site( $site );
5933
 
5934
  // Sync licenses.
6008
  if ( ! $background && is_admin() ) {
6009
  $this->_admin_notices->add(
6010
  sprintf(
6011
+ __fs( 'plan-did-not-change-message', $this->_slug ) . ' ' .
6012
  sprintf(
6013
  '<a href="%s">%s</a>',
6014
  $this->contact_url(
6015
  'bug',
6016
+ sprintf( __fs( 'plan-did-not-change-email-message', $this->_slug ),
6017
  strtoupper( $this->_site->plan->name )
6018
  )
6019
  ),
6020
+ __fs( 'contact-us-here', $this->_slug )
6021
  )
6022
  ),
6023
+ __fs( 'hmm', $this->_slug ) . '...',
6024
  'error'
6025
  );
6026
  }
6028
  case 'upgraded':
6029
  $this->_admin_notices->add_sticky(
6030
  sprintf(
6031
+ __fs( 'plan-upgraded-message', $this->_slug ),
6032
  '<i>' . $this->get_plugin_name() . '</i>'
6033
  ) . ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
6034
+ __fs( 'download-latest-x-version', $this->_slug ),
6035
  $this->_site->plan->title
6036
  ) )
6037
  ),
6038
  'plan_upgraded',
6039
+ __fs( 'yee-haw', $this->_slug ) . '!'
6040
  );
6041
 
6042
  $this->_admin_notices->remove_sticky( array(
6049
  case 'changed':
6050
  $this->_admin_notices->add_sticky(
6051
  sprintf(
6052
+ __fs( 'plan-changed-to-x-message', $this->_slug ),
6053
  $this->_site->plan->title
6054
  ),
6055
  'plan_changed'
6064
  break;
6065
  case 'downgraded':
6066
  $this->_admin_notices->add_sticky(
6067
+ sprintf( __fs( 'license-expired-blocking-message', $this->_slug ) ),
6068
  'license_expired',
6069
+ __fs( 'hmm', $this->_slug ) . '...'
6070
  );
6071
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6072
  break;
6073
  case 'expired':
6074
  $this->_admin_notices->add_sticky(
6075
+ sprintf( __fs( 'license-expired-non-blocking-message', $this->_slug ), $this->_site->plan->title ),
6076
  'license_expired',
6077
+ __fs( 'hmm', $this->_slug ) . '...'
6078
  );
6079
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6080
  break;
6081
  case 'trial_started':
6082
  $this->_admin_notices->add_sticky(
6083
  sprintf(
6084
+ __fs( 'trial-started-message', $this->_slug ),
6085
  '<i>' . $this->get_plugin_name() . '</i>'
6086
  ) . ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
6087
+ __fs( 'download-latest-x-version', $this->_slug ),
6088
  $this->_storage->trial_plan->title
6089
  ) ) ),
6090
  'trial_started',
6091
+ __fs( 'yee-haw', $this->_slug ) . '!'
6092
  );
6093
 
6094
  $this->_admin_notices->remove_sticky( array(
6097
  break;
6098
  case 'trial_expired':
6099
  $this->_admin_notices->add_sticky(
6100
+ __fs( 'trial-expired-message', $this->_slug ),
6101
  'trial_expired',
6102
+ __fs( 'hmm', $this->_slug ) . '...'
6103
  );
6104
  $this->_admin_notices->remove_sticky( array(
6105
  'trial_started',
6135
  if ( isset( $license->error ) ) {
6136
  if ( ! $background ) {
6137
  $this->_admin_notices->add(
6138
+ __fs( 'license-activation-failed-message', $this->_slug ) . '<br> ' .
6139
+ __fs( 'server-error-message', $this->_slug ) . ' ' . var_export( $license->error, true ),
6140
+ __fs( 'hmm', $this->_slug ) . '...',
6141
  'error'
6142
  );
6143
  }
6156
 
6157
  if ( ! $background ) {
6158
  $this->_admin_notices->add_sticky(
6159
+ __fs( 'license-activated-message', $this->_slug ) .
6160
  ( $this->is_premium() ? '' : ' ' . $this->_get_latest_download_link( sprintf(
6161
+ __fs( 'download-latest-x-version', $this->_slug ),
6162
  $this->_site->plan->title
6163
  ) ) ),
6164
  'license_activated',
6165
+ __fs( 'yee-haw', $this->_slug ) . '!'
6166
  );
6167
  }
6168
 
6183
 
6184
  if ( ! is_object( $this->_license ) ) {
6185
  $this->_admin_notices->add(
6186
+ sprintf( __fs( 'no-active-license-message', $this->_slug ), $this->_site->plan->title ),
6187
+ __fs( 'hmm', $this->_slug ) . '...'
6188
  );
6189
 
6190
  return;
6195
 
6196
  if ( isset( $license->error ) ) {
6197
  $this->_admin_notices->add(
6198
+ __fs( 'license-deactivation-failed-message', $this->_slug ) . '<br> ' .
6199
+ __fs( 'server-error-message', $this->_slug ) . ' ' . var_export( $license->error, true ),
6200
+ __fs( 'hmm', $this->_slug ) . '...',
6201
  'error'
6202
  );
6203
 
6222
 
6223
  if ( $show_notice ) {
6224
  $this->_admin_notices->add(
6225
+ sprintf( __fs( 'license-deactivation-message', $this->_slug ), $this->_site->plan->title ),
6226
+ __fs( 'ok', $this->_slug )
6227
  );
6228
  }
6229
 
6271
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6272
 
6273
  $this->_admin_notices->add(
6274
+ sprintf( __fs( 'plan-x-downgraded-message', $this->_slug ),
6275
  $plan->title,
6276
  human_time_diff( time(), strtotime( $this->_license->expiration ) )
6277
  )
6281
  $this->_store_site();
6282
  } else {
6283
  $this->_admin_notices->add(
6284
+ __fs( 'plan-downgraded-failure-message', $this->_slug ),
6285
+ __fs( 'oops', $this->_slug ) . '...',
6286
  'error'
6287
  );
6288
  }
6301
 
6302
  if ( ! $this->is_trial() ) {
6303
  $this->_admin_notices->add(
6304
+ __fs( 'trial-cancel-no-trial-message', $this->_slug ),
6305
+ __fs( 'oops', $this->_slug ) . '...',
6306
  'error'
6307
  );
6308
 
6331
  $this->_admin_notices->remove_sticky( 'plan_upgraded' );
6332
 
6333
  $this->_admin_notices->add(
6334
+ sprintf( __fs( 'trial-cancel-message', $this->_slug ), $this->_storage->trial_plan->title )
6335
  );
6336
 
6337
  $this->_admin_notices->remove_sticky( array(
6347
  unset( $this->_storage->trial_plan );
6348
  } else {
6349
  $this->_admin_notices->add(
6350
+ __fs( 'trial-cancel-failure-message', $this->_slug ),
6351
+ __fs( 'oops', $this->_slug ) . '...',
6352
  'error'
6353
  );
6354
  }
6572
  if ( ! $background ) {
6573
  $this->_admin_notices->add(
6574
  sprintf(
6575
+ __fs( 'version-x-released', $this->_slug ) . ' ' . __fs( 'please-download-x', $this->_slug ),
6576
  $update->version,
6577
  sprintf(
6578
  '<a href="%s" target="_blank">%s</a>',
6579
  $this->get_account_url( 'download_latest' ),
6580
+ sprintf( __fs( 'latest-x-version', $this->_slug ), $this->_site->plan->title )
6581
  )
6582
  ),
6583
+ __fs( 'new', $this->_slug ) . '!'
6584
  );
6585
  }
6586
  } else if ( false === $new_version && ! $background ) {
6587
  $this->_admin_notices->add(
6588
+ __fs( 'you-have-latest', $this->_slug ),
6589
+ __fs( 'you-are-good', $this->_slug )
6590
  );
6591
  }
6592
 
6784
 
6785
  if ( ! isset( $result->error ) ) {
6786
  $this->_admin_notices->add( sprintf(
6787
+ __fs( 'verification-email-sent-message', $this->_slug ),
6788
  sprintf( '<a href="mailto:%1s">%2s</a>', esc_url( $this->_user->email ), $this->_user->email )
6789
  ) );
6790
  } else {
6911
  $candidate_email = fs_request_get( 'candidate_email', '' );
6912
 
6913
  if ( $this->init_change_owner( $candidate_email ) ) {
6914
+ $this->_admin_notices->add( sprintf( __fs( 'change-owner-request-sent-x', $this->_slug ), '<b>' . $this->_user->email . '</b>' ) );
6915
  }
6916
  break;
6917
  case 'owner_confirmed':
6918
  $candidate_email = fs_request_get( 'candidate_email', '' );
6919
 
6920
+ $this->_admin_notices->add( sprintf( __fs( 'change-owner-request_owner-confirmed', $this->_slug ), '<b>' . $candidate_email . '</b>' ) );
6921
  break;
6922
  case 'candidate_confirmed':
6923
  if ( $this->complete_change_owner() ) {
6924
  $this->_admin_notices->add_sticky(
6925
+ sprintf( __fs( 'change-owner-request_candidate-confirmed', $this->_slug ), '<b>' . $this->_user->email . '</b>' ),
6926
  'ownership_changed',
6927
+ __fs( 'congrats', $this->_slug ) . '!'
6928
  );
6929
  } else {
6930
  // @todo Handle failed ownership change message.
6944
  switch ( $result->error->code ) {
6945
  case 'user_exist':
6946
  $this->_admin_notices->add(
6947
+ __fs( 'user-exist-message', $this->_slug ) . ' ' .
6948
+ sprintf( __fs( 'user-exist-message_ownership', $this->_slug ), '<b>' . $new_email . '</b>' ) .
6949
  sprintf(
6950
  '<a style="margin-left: 10px;" href="%s"><button class="button button-primary">%s &nbsp;&#10140;</button></a>',
6951
  $this->get_account_url( 'change_owner', array(
6952
  'state' => 'init',
6953
  'candidate_email' => $new_email
6954
  ) ),
6955
+ __fs( 'change-ownership', $this->_slug )
6956
  ),
6957
+ __fs( 'oops', $this->_slug ) . '...',
6958
  'error'
6959
  );
6960
  break;
6961
  }
6962
  } else {
6963
+ $this->_admin_notices->add( __fs( 'email-updated-message', $this->_slug ) );
6964
  }
6965
 
6966
  return;
6972
 
6973
  if ( isset( $result->error ) ) {
6974
  $this->_admin_notices->add(
6975
+ __fs( 'name-update-failed-message', $this->_slug ),
6976
+ __fs( 'oops', $this->_slug ) . '...',
6977
  'error'
6978
  );
6979
  } else {
6980
+ $this->_admin_notices->add( __fs( 'name-updated-message', $this->_slug ) );
6981
  }
6982
 
6983
  return;
7030
  $this->do_action( 'account_property_edit', 'site', $site_property, $site_property_value );
7031
 
7032
  $this->_admin_notices->add( sprintf(
7033
+ __fs( 'x-updated', $this->_slug ),
7034
  '<b>' . str_replace( '_', ' ', $p ) . '</b>' ) );
7035
 
7036
  return;
7124
 
7125
  if ( ! $this->is_registered() && $this->is_org_repo_compliant() ) {
7126
  $this->_admin_notices->add(
7127
+ sprintf( __fs( 'addons-info-external-message', $this->_slug ), '<b>' . $this->get_plugin_name() . '</b>' ),
7128
+ __fs( 'heads-up', $this->_slug ),
7129
  'update-nag'
7130
  );
7131
  }
7189
  *
7190
  * @uses remove_all_actions()
7191
  */
7192
+ private static function _hide_admin_notices() {
7193
  remove_all_actions( 'admin_notices' );
7194
  remove_all_actions( 'network_admin_notices' );
7195
  remove_all_actions( 'all_admin_notices' );
7196
  remove_all_actions( 'user_admin_notices' );
7197
  }
7198
 
7199
+ static function _clean_admin_content_section_hook() {
7200
+ self::_hide_admin_notices();
7201
 
7202
  // Hide footer.
7203
  echo '<style>#wpfooter { display: none !important; }</style>';
7209
  * @author Vova Feldman (@svovaf)
7210
  * @since 1.0.3
7211
  */
7212
+ static function _clean_admin_content_section() {
7213
+ add_action( 'admin_head', 'Freemius::_clean_admin_content_section_hook' );
7214
  }
7215
 
7216
  /* CSS & JavaScript
7364
  $require_subscription = $paid_plan->is_require_subscription;
7365
  $upgrade_url = $this->get_trial_url();
7366
  $cc_string = $require_subscription ?
7367
+ sprintf( __fs( 'no-commitment-for-x-days', $this->_slug ), $paid_plan->trial_period ) :
7368
+ __fs( 'no-cc-required', $this->_slug ) . '!';
7369
 
7370
 
7371
  $total_paid_plans = count( $this->_plans ) - ( FS_Plan_Manager::instance()->has_free_plan( $this->_plans ) ? 1 : 0 );
7373
  if ( $total_paid_plans === $trial_plans_count ) {
7374
  // All paid plans have trials.
7375
  $message = sprintf(
7376
+ __fs( 'hey', $this->_slug ) . '! ' . __fs( 'trial-x-promotion-message', $this->_slug ),
7377
  sprintf( '<b>%s</b>', $this->get_plugin_name() ),
7378
+ strtolower( __fs( 'awesome', $this->_slug ) ),
7379
  $paid_plan->trial_period
7380
  );
7381
  } else {
7392
 
7393
  // Not all paid plans have trials.
7394
  $message = sprintf(
7395
+ __fs( 'hey', $this->_slug ) . '! ' . __fs( 'trial-x-promotion-message', $this->_slug ),
7396
  sprintf( '<b>%s</b>', $this->get_plugin_name() ),
7397
  $plans_string,
7398
  $paid_plan->trial_period
7403
 
7404
  // Add start trial button.
7405
  $message .= ' ' . sprintf(
7406
+ '<a style="margin-left: 10px; vertical-align: super;" href="%s"><button class="button button-primary">%s &nbsp;&#10140;</button></a>',
7407
  $upgrade_url,
7408
+ __fs( 'start-free-trial', $this->_slug )
7409
  );
7410
 
7411
  $this->_admin_notices->add_sticky(
7502
  if ( $this->is_registered() ) {
7503
  if ( ! $this->is_paying() && $this->has_paid_plan() ) {
7504
  $this->add_plugin_action_link(
7505
+ __fs( 'upgrade', $this->_slug ),
7506
  $this->get_upgrade_url(),
7507
  false,
7508
  20,
7512
 
7513
  if ( $this->_has_addons() ) {
7514
  $this->add_plugin_action_link(
7515
+ __fs( 'add-ons', $this->_slug ),
7516
  $this->_get_admin_page_url( 'addons' ),
7517
  false,
7518
  WP_FS__DEFAULT_PRIORITY,
7735
 
7736
  #endregion ------------------------------------------------------------------
7737
 
7738
+ #region Permissions ------------------------------------------------------------------
7739
+
7740
+ /**
7741
+ * Check if specific permission requested.
7742
+ *
7743
+ * @author Vova Feldman (@svovaf)
7744
+ * @since 1.1.6
7745
+ *
7746
+ * @param string $permission
7747
+ *
7748
+ * @return bool
7749
+ */
7750
+ function is_permission_requested( $permission ) {
7751
+ return isset( $this->_permissions[ $permission ] ) && ( true === $this->_permissions[ $permission ] );
7752
+ }
7753
+
7754
+ #endregion Permissions ------------------------------------------------------------------
7755
+
7756
  #region Marketing ------------------------------------------------------------------
7757
 
7758
  /**
lib/freemius/includes/class-fs-api.php CHANGED
@@ -31,7 +31,7 @@
31
  private static $_options;
32
 
33
  /**
34
- * @var FS_Option_Manager API Caching layer
35
  */
36
  private static $_cache;
37
 
@@ -70,9 +70,7 @@
70
  $identifier = md5( $slug . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
71
 
72
  if ( ! isset( self::$_instances[ $identifier ] ) ) {
73
- if ( 0 === count( self::$_instances ) ) {
74
- self::_init();
75
- }
76
 
77
  self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox );
78
  }
@@ -81,12 +79,16 @@
81
  }
82
 
83
  private static function _init() {
 
 
 
 
84
  if ( ! class_exists( 'Freemius_Api' ) ) {
85
  require_once( WP_FS__DIR_SDK . '/Freemius.php' );
86
  }
87
 
88
  self::$_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true );
89
- self::$_cache = FS_Option_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME, true );
90
 
91
  self::$_clock_diff = self::$_options->get_option( 'api_clock_diff', 0 );
92
  Freemius_Api::SetClockDiff( self::$_clock_diff );
@@ -123,7 +125,7 @@
123
 
124
  // Sync clock and store.
125
  $new_clock_diff = ( false === $diff ) ?
126
- $this->_api->FindClockDiff() :
127
  $diff;
128
 
129
  if ( $new_clock_diff === self::$_clock_diff ) {
@@ -133,7 +135,7 @@
133
  self::$_clock_diff = $new_clock_diff;
134
 
135
  // Update API clock's diff.
136
- $this->_api->SetClockDiff( self::$_clock_diff );
137
 
138
  // Store new clock diff in storage.
139
  self::$_options->set_option( 'api_clock_diff', self::$_clock_diff, true );
@@ -154,26 +156,31 @@
154
  private function _call( $path, $method = 'GET', $params = array(), $retry = false ) {
155
  $this->_logger->entrance();
156
 
157
- $result = $this->_api->Api( $path, $method, $params );
158
-
159
- if ( null !== $result &&
160
- isset( $result->error ) &&
161
- 'request_expired' === $result->error->code
162
- ) {
163
- if ( ! $retry ) {
164
- $diff = isset( $result->error->timestamp ) ?
165
- ( time() - strtotime( $result->error->timestamp ) ) :
166
- false;
167
-
168
- // Try to sync clock diff.
169
- if ( false !== $this->_sync_clock_diff( $diff ) ) {
170
- // Retry call with new synced clock.
171
- return $this->_call( $path, $method, $params, true );
 
 
 
 
 
172
  }
173
  }
174
  }
175
 
176
- if ( null !== $result && isset( $result->error ) ) {
177
  // Log API errors.
178
  $this->_logger->error( $result->error->message );
179
  }
@@ -214,6 +221,8 @@
214
  * @return stdClass|mixed
215
  */
216
  function get( $path = '/', $flush = false, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
 
 
217
  $cache_key = $this->get_cache_key( $path );
218
 
219
  // Always flush during development.
@@ -221,30 +230,19 @@
221
  $flush = true;
222
  }
223
 
224
- // Get result from cache.
225
- $cache_entry = self::$_cache->get_option( $cache_key, false );
226
-
227
- $fetch = false;
228
- if ( $flush ||
229
- false === $cache_entry ||
230
- ! isset( $cache_entry->timestamp ) ||
231
- ! is_numeric( $cache_entry->timestamp ) ||
232
- $cache_entry->timestamp < WP_FS__SCRIPT_START_TIME
233
- ) {
234
- $fetch = true;
235
- }
236
 
237
- if ( $fetch ) {
238
  $result = $this->call( $path );
239
 
240
  if ( ! is_object( $result ) || isset( $result->error ) ) {
241
- if ( is_object( $cache_entry ) &&
242
- isset( $cache_entry->result ) &&
243
- ! isset( $cache_entry->result->error )
244
  ) {
245
  // If there was an error during a newer data fetch,
246
  // fallback to older data version.
247
- $result = $cache_entry->result;
248
  } else {
249
  // If no older data version, return result without
250
  // caching the error.
@@ -252,13 +250,12 @@
252
  }
253
  }
254
 
255
- $cache_entry = new stdClass();
256
- $cache_entry->result = $result;
257
- $cache_entry->timestamp = WP_FS__SCRIPT_START_TIME + $expiration;
258
- self::$_cache->set_option( $cache_key, $cache_entry, true );
259
  }
260
 
261
- return $cache_entry->result;
262
  }
263
 
264
  private function get_cache_key( $path, $method = 'GET', $params = array() ) {
@@ -271,38 +268,81 @@
271
  /**
272
  * Test API connectivity.
273
  *
 
274
  * @since 1.0.9 If fails, try to fallback to HTTP.
275
- *
276
- * @param null|string $unique_anonymous_id
277
  *
278
  * @return bool True if successful connectivity to the API.
279
  */
280
- function test( $unique_anonymous_id = null ) {
281
- $this->_logger->entrance();
282
 
283
- if ( ! function_exists( 'curl_version' ) ) {
284
- // cUrl extension is not active.
285
- return false;
286
- }
287
 
288
- $test = is_null( $unique_anonymous_id ) ?
289
- $this->_api->Test() :
290
- $this->_api->Test( $this->_call( 'ping.json?uid=' . $unique_anonymous_id ) );
291
 
292
- if ( false === $test && $this->_api->IsHttps() ) {
293
- // Fallback to HTTP, since HTTPS fails.
294
- $this->_api->SetHttp();
295
 
296
- self::$_options->set_option( 'api_force_http', true, true );
 
 
 
 
297
 
298
- $test = is_null( $unique_anonymous_id ) ?
299
- $this->_api->Test() :
300
- $this->_api->Test( $this->_call( 'ping.json?uid=' . $unique_anonymous_id ) );
 
 
 
 
 
 
 
 
 
 
 
301
  }
302
 
303
  return $test;
304
  }
305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  /**
307
  * Ping API for connectivity test, and return result object.
308
  *
@@ -315,12 +355,70 @@
315
  * @return object
316
  */
317
  function ping( $unique_anonymous_id = null, $is_update = false ) {
318
- return is_null( $unique_anonymous_id ) ?
319
- $this->_api->Ping() :
 
 
 
 
 
 
320
  $this->_call( 'ping.json?' . http_build_query( array(
321
  'uid' => $unique_anonymous_id,
322
  'is_update' => $is_update,
323
  ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  }
325
 
326
  /**
@@ -334,11 +432,11 @@
334
  * @return bool
335
  */
336
  function is_valid_ping( $pong ) {
337
- return $this->_api->Test( $pong );
338
  }
339
 
340
  function get_url( $path = '' ) {
341
- return $this->_api->GetUrl( $path );
342
  }
343
 
344
  /**
@@ -348,7 +446,9 @@
348
  * @since 1.0.9
349
  */
350
  static function clear_cache() {
351
- self::$_cache = FS_Option_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME, true );
352
- self::$_cache->clear( true );
 
 
353
  }
354
  }
31
  private static $_options;
32
 
33
  /**
34
+ * @var FS_Cache_Manager API Caching layer
35
  */
36
  private static $_cache;
37
 
70
  $identifier = md5( $slug . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
71
 
72
  if ( ! isset( self::$_instances[ $identifier ] ) ) {
73
+ self::_init();
 
 
74
 
75
  self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox );
76
  }
79
  }
80
 
81
  private static function _init() {
82
+ if ( isset( self::$_options ) ) {
83
+ return;
84
+ }
85
+
86
  if ( ! class_exists( 'Freemius_Api' ) ) {
87
  require_once( WP_FS__DIR_SDK . '/Freemius.php' );
88
  }
89
 
90
  self::$_options = FS_Option_Manager::get_manager( WP_FS__OPTIONS_OPTION_NAME, true );
91
+ self::$_cache = FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME );
92
 
93
  self::$_clock_diff = self::$_options->get_option( 'api_clock_diff', 0 );
94
  Freemius_Api::SetClockDiff( self::$_clock_diff );
125
 
126
  // Sync clock and store.
127
  $new_clock_diff = ( false === $diff ) ?
128
+ Freemius_Api::FindClockDiff() :
129
  $diff;
130
 
131
  if ( $new_clock_diff === self::$_clock_diff ) {
135
  self::$_clock_diff = $new_clock_diff;
136
 
137
  // Update API clock's diff.
138
+ Freemius_Api::SetClockDiff( self::$_clock_diff );
139
 
140
  // Store new clock diff in storage.
141
  self::$_options->set_option( 'api_clock_diff', self::$_clock_diff, true );
156
  private function _call( $path, $method = 'GET', $params = array(), $retry = false ) {
157
  $this->_logger->entrance();
158
 
159
+ if ( self::is_temporary_down() ) {
160
+ $result = $this->get_temporary_unavailable_error();
161
+ } else {
162
+ $result = $this->_api->Api( $path, $method, $params );
163
+
164
+ if ( null !== $result &&
165
+ isset( $result->error ) &&
166
+ isset( $result->error->code ) &&
167
+ 'request_expired' === $result->error->code
168
+ ) {
169
+ if ( ! $retry ) {
170
+ $diff = isset( $result->error->timestamp ) ?
171
+ ( time() - strtotime( $result->error->timestamp ) ) :
172
+ false;
173
+
174
+ // Try to sync clock diff.
175
+ if ( false !== $this->_sync_clock_diff( $diff ) ) {
176
+ // Retry call with new synced clock.
177
+ return $this->_call( $path, $method, $params, true );
178
+ }
179
  }
180
  }
181
  }
182
 
183
+ if ( null !== $result && isset( $result->error ) && isset( $result->error->message ) ) {
184
  // Log API errors.
185
  $this->_logger->error( $result->error->message );
186
  }
221
  * @return stdClass|mixed
222
  */
223
  function get( $path = '/', $flush = false, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
224
+ $this->_logger->entrance();
225
+
226
  $cache_key = $this->get_cache_key( $path );
227
 
228
  // Always flush during development.
230
  $flush = true;
231
  }
232
 
233
+ $cached_result = self::$_cache->get( $cache_key );
 
 
 
 
 
 
 
 
 
 
 
234
 
235
+ if ( $flush || ! self::$_cache->has_valid( $cache_key ) ) {
236
  $result = $this->call( $path );
237
 
238
  if ( ! is_object( $result ) || isset( $result->error ) ) {
239
+ // Api returned an error.
240
+ if ( is_object( $cached_result ) &&
241
+ ! isset( $cached_result )
242
  ) {
243
  // If there was an error during a newer data fetch,
244
  // fallback to older data version.
245
+ $result = $cached_result;
246
  } else {
247
  // If no older data version, return result without
248
  // caching the error.
250
  }
251
  }
252
 
253
+ self::$_cache->set( $cache_key, $result, $expiration );
254
+
255
+ $cached_result = $result;
 
256
  }
257
 
258
+ return $cached_result;
259
  }
260
 
261
  private function get_cache_key( $path, $method = 'GET', $params = array() ) {
268
  /**
269
  * Test API connectivity.
270
  *
271
+ * @author Vova Feldman (@svovaf)
272
  * @since 1.0.9 If fails, try to fallback to HTTP.
273
+ * @since 1.1.6 Added a 5-min caching mechanism, to prevent from overloading the server if the API if
274
+ * temporary down.
275
  *
276
  * @return bool True if successful connectivity to the API.
277
  */
278
+ static function test() {
279
+ self::_init();
280
 
281
+ $cache_key = 'ping_test';
 
 
 
282
 
283
+ $test = self::$_cache->get_valid( $cache_key, null );
 
 
284
 
285
+ if ( is_null( $test ) ) {
286
+ $test = Freemius_Api::Test();
 
287
 
288
+ if ( false === $test && Freemius_Api::IsHttps() ) {
289
+ // Fallback to HTTP, since HTTPS fails.
290
+ Freemius_Api::SetHttp();
291
+
292
+ self::$_options->set_option( 'api_force_http', true, true );
293
 
294
+ $test = Freemius_Api::Test();
295
+
296
+ if ( false === $test ) {
297
+ /**
298
+ * API connectivity test fail also in HTTP request, therefore,
299
+ * fallback to HTTPS to keep connection secure.
300
+ *
301
+ * @since 1.1.6
302
+ */
303
+ self::$_options->set_option( 'api_force_http', false, true );
304
+ }
305
+ }
306
+
307
+ self::$_cache->set( $cache_key, $test, WP_FS__TIME_5_MIN_IN_SEC );
308
  }
309
 
310
  return $test;
311
  }
312
 
313
+ /**
314
+ * Check if API is temporary down.
315
+ *
316
+ * @author Vova Feldman (@svovaf)
317
+ * @since 1.1.6
318
+ *
319
+ * @return bool
320
+ */
321
+ static function is_temporary_down() {
322
+ self::_init();
323
+
324
+ $test = self::$_cache->get_valid( 'ping_test', null );
325
+
326
+ return ( false === $test );
327
+ }
328
+
329
+ /**
330
+ * @author Vova Feldman (@svovaf)
331
+ * @since 1.1.6
332
+ *
333
+ * @return object
334
+ */
335
+ private function get_temporary_unavailable_error() {
336
+ return (object) array(
337
+ 'error' => array(
338
+ 'type' => 'TemporaryUnavailable',
339
+ 'message' => 'API is temporary unavailable.',
340
+ 'code' => 'temporary_unavailable',
341
+ 'http' => 503
342
+ )
343
+ );
344
+ }
345
+
346
  /**
347
  * Ping API for connectivity test, and return result object.
348
  *
355
  * @return object
356
  */
357
  function ping( $unique_anonymous_id = null, $is_update = false ) {
358
+ $this->_logger->entrance();
359
+
360
+ if ( self::is_temporary_down() ) {
361
+ return $this->get_temporary_unavailable_error();
362
+ }
363
+
364
+ $pong = is_null( $unique_anonymous_id ) ?
365
+ Freemius_Api::Ping() :
366
  $this->_call( 'ping.json?' . http_build_query( array(
367
  'uid' => $unique_anonymous_id,
368
  'is_update' => $is_update,
369
  ) ) );
370
+
371
+ if ( $this->is_valid_ping( $pong ) ) {
372
+ return $pong;
373
+ }
374
+
375
+ if ( self::should_try_with_http( $pong ) ) {
376
+ // Fallback to HTTP, since HTTPS fails.
377
+ Freemius_Api::SetHttp();
378
+
379
+ self::$_options->set_option( 'api_force_http', true, true );
380
+
381
+ $pong = is_null( $unique_anonymous_id ) ?
382
+ Freemius_Api::Ping() :
383
+ $this->_call( 'ping.json?' . http_build_query( array(
384
+ 'uid' => $unique_anonymous_id,
385
+ 'is_update' => $is_update,
386
+ ) ) );
387
+
388
+ if ( ! $this->is_valid_ping( $pong ) ) {
389
+ self::$_options->set_option( 'api_force_http', false, true );
390
+ }
391
+ }
392
+
393
+ return $pong;
394
+ }
395
+
396
+ /**
397
+ * Check if based on the API result we should try
398
+ * to re-run the same request with HTTP instead of HTTPS.
399
+ *
400
+ * @author Vova Feldman (@svovaf)
401
+ * @since 1.1.6
402
+ *
403
+ * @param $result
404
+ *
405
+ * @return bool
406
+ */
407
+ private static function should_try_with_http($result) {
408
+ if ( ! Freemius_Api::IsHttps() ) {
409
+ return false;
410
+ }
411
+
412
+ return ( ! is_object( $result ) ||
413
+ ! isset( $result->error ) ||
414
+ ! isset( $result->error->code ) ||
415
+ ! in_array( $result->error->code, array(
416
+ 'curl_missing',
417
+ 'cloudflare_ddos_protection',
418
+ 'squid_cache_block',
419
+ 'too_many_requests',
420
+ ) ) );
421
+
422
  }
423
 
424
  /**
432
  * @return bool
433
  */
434
  function is_valid_ping( $pong ) {
435
+ return Freemius_Api::Test( $pong );
436
  }
437
 
438
  function get_url( $path = '' ) {
439
+ return Freemius_Api::GetUrl( $path, $this->_api->IsSandbox() );
440
  }
441
 
442
  /**
446
  * @since 1.0.9
447
  */
448
  static function clear_cache() {
449
+ self::_init();
450
+
451
+ self::$_cache = FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME );
452
+ self::$_cache->clear();
453
  }
454
  }
lib/freemius/includes/class-fs-plugin-updater.php CHANGED
@@ -52,6 +52,26 @@
52
  'pre_set_site_transient_update_plugins_filter'
53
  ) );
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  if ( ! WP_FS__IS_PRODUCTION_MODE ) {
56
  add_filter( 'http_request_host_is_external', array(
57
  $this,
@@ -60,6 +80,47 @@
60
  }
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  /**
64
  * Since WP version 3.6, a new security feature was added that denies access to repository with a local ip.
65
  * During development mode we want to be able updating plugin versions via our localhost repository. This
@@ -233,7 +294,7 @@ if ( !isset($info->error) ) {
233
  $new_version = $this->_fs->_fetch_latest_version( $is_addon ? $addon->id : false );
234
 
235
  if ( $is_addon ) {
236
- $data->name = $addon->title . ' ' . __fs( 'addon' );
237
  $data->slug = $addon->slug;
238
  $data->url = WP_FS__ADDRESS;
239
  $data->package = $new_version->url;
52
  'pre_set_site_transient_update_plugins_filter'
53
  ) );
54
 
55
+ if ( ! $this->_fs->has_active_license() ) {
56
+ /**
57
+ * If user has the premium plugin's code but do NOT have an active license,
58
+ * encourage him to upgrade by showing that there's a new release, but instead
59
+ * of showing an update link, show upgrade link to the pricing page.
60
+ *
61
+ * @since 1.1.6
62
+ *
63
+ */
64
+ // WP 2.9+
65
+ add_action( "after_plugin_row_{$this->_fs->get_plugin_basename()}", array(
66
+ &$this,
67
+ 'catch_plugin_update_row'
68
+ ), 9 );
69
+ add_action( "after_plugin_row_{$this->_fs->get_plugin_basename()}", array(
70
+ &$this,
71
+ 'edit_and_echo_plugin_update_row'
72
+ ), 11, 2 );
73
+ }
74
+
75
  if ( ! WP_FS__IS_PRODUCTION_MODE ) {
76
  add_filter( 'http_request_host_is_external', array(
77
  $this,
80
  }
81
  }
82
 
83
+ /**
84
+ * Capture plugin update row by turning output buffering.
85
+ *
86
+ * @author Vova Feldman (@svovaf)
87
+ * @since 1.1.6
88
+ */
89
+ function catch_plugin_update_row() {
90
+ ob_start();
91
+ }
92
+
93
+ /**
94
+ * Overrides default update message format with "renew your license" message.
95
+ *
96
+ * @author Vova Feldman (@svovaf)
97
+ * @since 1.1.6
98
+ */
99
+ function edit_and_echo_plugin_update_row( $file, $plugin_data ) {
100
+ $plugin_update_row = ob_get_clean();
101
+
102
+ $current = get_site_transient( 'update_plugins' );
103
+ if ( ! isset( $current->response[ $file ] ) ) {
104
+ echo $plugin_update_row;
105
+
106
+ return false;
107
+ }
108
+
109
+ $r = $current->response[ $file ];
110
+
111
+ $plugin_update_row = preg_replace(
112
+ '/(\<div.+>)(.+)(\<a.+\<a.+)\<\/div\>/is',
113
+ '$1 $2 ' . sprintf(
114
+ __fs( 'renew-license-now' ),
115
+ '<a href="' . $this->_fs->pricing_url() . '">', '</a>',
116
+ $r->new_version ) .
117
+ '$4',
118
+ $plugin_update_row
119
+ );
120
+
121
+ echo $plugin_update_row;
122
+ }
123
+
124
  /**
125
  * Since WP version 3.6, a new security feature was added that denies access to repository with a local ip.
126
  * During development mode we want to be able updating plugin versions via our localhost repository. This
294
  $new_version = $this->_fs->_fetch_latest_version( $is_addon ? $addon->id : false );
295
 
296
  if ( $is_addon ) {
297
+ $data->name = $addon->title . ' ' . __fs( 'addon', $this->_fs->get_slug() );
298
  $data->slug = $addon->slug;
299
  $data->url = WP_FS__ADDRESS;
300
  $data->package = $new_version->url;
lib/freemius/includes/entities/class-fs-site.php CHANGED
@@ -78,7 +78,7 @@
78
 
79
  parent::__construct( $site );
80
 
81
- if ( is_object( $site ) && isset( $site->plan_id ) ) {
82
  $this->plan->id = $site->plan_id;
83
  }
84
  }
78
 
79
  parent::__construct( $site );
80
 
81
+ if ( is_object( $site ) ) {
82
  $this->plan->id = $site->plan_id;
83
  }
84
  }
lib/freemius/includes/fs-core-functions.php CHANGED
@@ -58,20 +58,6 @@
58
  return ob_get_clean();
59
  }
60
 
61
- function __fs( $key ) {
62
- global $fs_text;
63
-
64
- if ( ! isset( $fs_text ) ) {
65
- require_once( dirname( __FILE__ ) . '/i18n.php' );
66
- }
67
-
68
- return isset( $fs_text[ $key ] ) ? $fs_text[ $key ] : $key;
69
- }
70
-
71
- function _efs( $key ) {
72
- echo __fs( $key );
73
- }
74
-
75
  /* Scripts and styles including.
76
  --------------------------------------------------------------------------------------------*/
77
  function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
@@ -96,8 +82,8 @@
96
  wp_enqueue_script( $handle, plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $in_footer );
97
  }
98
 
99
- function fs_img_url( $path ) {
100
- return plugins_url( plugin_basename( WP_FS__DIR_IMG . '/' . trim( $path, '/' ) ) );
101
  }
102
 
103
  /* Request handlers.
@@ -152,34 +138,6 @@
152
  return ( is_admin() && $_REQUEST['page'] === $menu_slug );
153
  }
154
 
155
- /**
156
- * Get client IP.
157
- *
158
- * @author Vova Feldman (@svovaf)
159
- * @since 1.1.2
160
- *
161
- * @return string|null
162
- */
163
- function fs_get_ip() {
164
- $fields = array(
165
- 'HTTP_CF_CONNECTING_IP',
166
- 'HTTP_CLIENT_IP',
167
- 'HTTP_X_FORWARDED_FOR',
168
- 'HTTP_X_FORWARDED',
169
- 'HTTP_FORWARDED_FOR',
170
- 'HTTP_FORWARDED',
171
- 'REMOTE_ADDR',
172
- );
173
-
174
- foreach ( $fields as $ip_field ) {
175
- if ( ! empty( $_SERVER[ $ip_field ] ) ) {
176
- return $_SERVER[ $ip_field ];
177
- }
178
- }
179
-
180
- return null;
181
- }
182
-
183
  /* Core UI.
184
  --------------------------------------------------------------------------------------------*/
185
  function fs_ui_action_button( $slug, $page, $action, $title, $params = array(), $is_primary = true ) {
@@ -194,91 +152,6 @@
194
  href="<?php echo wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php
195
  }
196
 
197
- /* Core Redirect (copied from BuddyPress).
198
- --------------------------------------------------------------------------------------------*/
199
- /**
200
- * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
201
- *
202
- * @link http://support.microsoft.com/kb/q176113/
203
- * @since 1.5.1
204
- * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
205
- *
206
- * @param string $location The path to redirect to
207
- * @param int $status Status code to use
208
- *
209
- * @return bool False if $location is not set
210
- */
211
- function fs_redirect( $location, $status = 302 ) {
212
- global $is_IIS;
213
-
214
- if ( headers_sent() ) {
215
- return false;
216
- }
217
-
218
- if ( ! $location ) // allows the wp_redirect filter to cancel a redirect
219
- {
220
- return false;
221
- }
222
-
223
- $location = fs_sanitize_redirect( $location );
224
-
225
- if ( $is_IIS ) {
226
- header( "Refresh: 0;url=$location" );
227
- } else {
228
- if ( php_sapi_name() != 'cgi-fcgi' ) {
229
- status_header( $status );
230
- } // This causes problems on IIS and some FastCGI setups
231
- header( "Location: $location" );
232
- }
233
-
234
- return true;
235
- }
236
-
237
- /**
238
- * Sanitizes a URL for use in a redirect.
239
- *
240
- * @since 2.3
241
- *
242
- * @param string $location
243
- *
244
- * @return string redirect-sanitized URL
245
- */
246
- function fs_sanitize_redirect( $location ) {
247
- $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location );
248
- $location = fs_kses_no_null( $location );
249
-
250
- // remove %0d and %0a from location
251
- $strip = array( '%0d', '%0a' );
252
- $found = true;
253
- while ( $found ) {
254
- $found = false;
255
- foreach ( (array) $strip as $val ) {
256
- while ( strpos( $location, $val ) !== false ) {
257
- $found = true;
258
- $location = str_replace( $val, '', $location );
259
- }
260
- }
261
- }
262
-
263
- return $location;
264
- }
265
-
266
- /**
267
- * Removes any NULL characters in $string.
268
- *
269
- * @since 1.0.0
270
- *
271
- * @param string $string
272
- *
273
- * @return string
274
- */
275
- function fs_kses_no_null( $string ) {
276
- $string = preg_replace( '/\0+/', '', $string );
277
- $string = preg_replace( '/(\\\\0)+/', '', $string );
278
-
279
- return $string;
280
- }
281
-
282
  /*function fs_error_handler($errno, $errstr, $errfile, $errline)
283
  {
284
  if (false === strpos($errfile, 'freemius/'))
@@ -302,29 +175,6 @@
302
 
303
  set_error_handler('fs_error_handler');*/
304
 
305
- if ( function_exists( 'wp_normalize_path' ) ) {
306
- /**
307
- * Normalize a filesystem path.
308
- *
309
- * Replaces backslashes with forward slashes for Windows systems, and ensures
310
- * no duplicate slashes exist.
311
- *
312
- * @param string $path Path to normalize.
313
- *
314
- * @return string Normalized path.
315
- */
316
- function fs_normalize_path( $path ) {
317
- return wp_normalize_path( $path );
318
- }
319
- } else {
320
- function fs_normalize_path( $path ) {
321
- $path = str_replace( '\\', '/', $path );
322
- $path = preg_replace( '|/+|', '/', $path );
323
-
324
- return $path;
325
- }
326
- }
327
-
328
  function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) {
329
  // $actionurl = str_replace( '&amp;', '&', $actionurl );
330
  return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
58
  return ob_get_clean();
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  /* Scripts and styles including.
62
  --------------------------------------------------------------------------------------------*/
63
  function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
82
  wp_enqueue_script( $handle, plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $in_footer );
83
  }
84
 
85
+ function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) {
86
+ return plugins_url( plugin_basename( $img_dir . '/' . trim( $path, '/' ) ) );
87
  }
88
 
89
  /* Request handlers.
138
  return ( is_admin() && $_REQUEST['page'] === $menu_slug );
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  /* Core UI.
142
  --------------------------------------------------------------------------------------------*/
143
  function fs_ui_action_button( $slug, $page, $action, $title, $params = array(), $is_primary = true ) {
152
  href="<?php echo wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  /*function fs_error_handler($errno, $errstr, $errfile, $errline)
156
  {
157
  if (false === strpos($errfile, 'freemius/'))
175
 
176
  set_error_handler('fs_error_handler');*/
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) {
179
  // $actionurl = str_replace( '&amp;', '&', $actionurl );
180
  return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
lib/freemius/includes/fs-essential-functions.php ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.1.5
7
+ */
8
+
9
+ if ( ! function_exists( 'fs_normalize_path' ) ) {
10
+ if ( function_exists( 'wp_normalize_path' ) ) {
11
+ /**
12
+ * Normalize a filesystem path.
13
+ *
14
+ * Replaces backslashes with forward slashes for Windows systems, and ensures
15
+ * no duplicate slashes exist.
16
+ *
17
+ * @param string $path Path to normalize.
18
+ *
19
+ * @return string Normalized path.
20
+ */
21
+ function fs_normalize_path( $path ) {
22
+ return wp_normalize_path( $path );
23
+ }
24
+ } else {
25
+ function fs_normalize_path( $path ) {
26
+ $path = str_replace( '\\', '/', $path );
27
+ $path = preg_replace( '|/+|', '/', $path );
28
+
29
+ return $path;
30
+ }
31
+ }
32
+ }
33
+
34
+ #region Core Redirect (copied from BuddyPress) -----------------------------------------
35
+
36
+ if ( ! function_exists( 'fs_redirect' ) ) {
37
+ /**
38
+ * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
39
+ *
40
+ * @link http://support.microsoft.com/kb/q176113/
41
+ * @since 1.5.1
42
+ * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
43
+ *
44
+ * @param string $location The path to redirect to
45
+ * @param int $status Status code to use
46
+ *
47
+ * @return bool False if $location is not set
48
+ */
49
+ function fs_redirect( $location, $status = 302 ) {
50
+ global $is_IIS;
51
+
52
+ if ( headers_sent() ) {
53
+ return false;
54
+ }
55
+
56
+ if ( ! $location ) // allows the wp_redirect filter to cancel a redirect
57
+ {
58
+ return false;
59
+ }
60
+
61
+ $location = fs_sanitize_redirect( $location );
62
+
63
+ if ( $is_IIS ) {
64
+ header( "Refresh: 0;url=$location" );
65
+ } else {
66
+ if ( php_sapi_name() != 'cgi-fcgi' ) {
67
+ status_header( $status );
68
+ } // This causes problems on IIS and some FastCGI setups
69
+ header( "Location: $location" );
70
+ }
71
+
72
+ return true;
73
+ }
74
+
75
+ /**
76
+ * Sanitizes a URL for use in a redirect.
77
+ *
78
+ * @since 2.3
79
+ *
80
+ * @param string $location
81
+ *
82
+ * @return string redirect-sanitized URL
83
+ */
84
+ function fs_sanitize_redirect( $location ) {
85
+ $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location );
86
+ $location = fs_kses_no_null( $location );
87
+
88
+ // remove %0d and %0a from location
89
+ $strip = array( '%0d', '%0a' );
90
+ $found = true;
91
+ while ( $found ) {
92
+ $found = false;
93
+ foreach ( (array) $strip as $val ) {
94
+ while ( strpos( $location, $val ) !== false ) {
95
+ $found = true;
96
+ $location = str_replace( $val, '', $location );
97
+ }
98
+ }
99
+ }
100
+
101
+ return $location;
102
+ }
103
+
104
+ /**
105
+ * Removes any NULL characters in $string.
106
+ *
107
+ * @since 1.0.0
108
+ *
109
+ * @param string $string
110
+ *
111
+ * @return string
112
+ */
113
+ function fs_kses_no_null( $string ) {
114
+ $string = preg_replace( '/\0+/', '', $string );
115
+ $string = preg_replace( '/(\\\\0)+/', '', $string );
116
+
117
+ return $string;
118
+ }
119
+ }
120
+
121
+ #endregion Core Redirect (copied from BuddyPress) -----------------------------------------
122
+
123
+ if ( ! function_exists( '__fs' ) ) {
124
+ global $fs_text_overrides;
125
+
126
+ if ( ! isset( $fs_text_overrides ) ) {
127
+ $fs_text_overrides = array();
128
+ }
129
+
130
+ /**
131
+ * Retrieve a translated text by key.
132
+ *
133
+ * @author Vova Feldman (@svovaf)
134
+ * @since 1.1.4
135
+ *
136
+ * @param string $key
137
+ * @param string $slug
138
+ *
139
+ * @return string
140
+ *
141
+ * @global $fs_text , $fs_text_overrides
142
+ */
143
+ function __fs( $key, $slug = 'freemius' ) {
144
+ global $fs_text, $fs_text_overrides;
145
+
146
+ if ( ! isset( $fs_text ) ) {
147
+ require_once( dirname( __FILE__ ) . '/i18n.php' );
148
+ }
149
+
150
+ if ( isset( $fs_text_overrides[ $slug ] ) &&
151
+ isset( $fs_text_overrides[ $slug ][ $key ] )
152
+ ) {
153
+ return $fs_text_overrides[ $slug ][ $key ];
154
+ }
155
+
156
+ return isset( $fs_text[ $key ] ) ?
157
+ $fs_text[ $key ] :
158
+ $key;
159
+ }
160
+
161
+ /**
162
+ * Display a translated text by key.
163
+ *
164
+ * @author Vova Feldman (@svovaf)
165
+ * @since 1.1.4
166
+ *
167
+ * @param string $key
168
+ * @param string $slug
169
+ */
170
+ function _efs( $key, $slug = 'freemius' ) {
171
+ echo __fs( $key, $slug );
172
+ }
173
+
174
+ /**
175
+ * Override default i18n text phrases.
176
+ *
177
+ * @author Vova Feldman (@svovaf)
178
+ * @since 1.1.6
179
+ *
180
+ * @param string[] $key_value
181
+ * @param string $slug
182
+ *
183
+ * @global $fs_text_overrides
184
+ */
185
+ function fs_override_i18n( array $key_value, $slug = 'freemius' ) {
186
+ global $fs_text_overrides;
187
+
188
+ if ( ! isset( $fs_text_overrides[ $slug ] ) ) {
189
+ $fs_text_overrides[ $slug ] = array();
190
+ }
191
+
192
+ foreach ( $key_value as $key => $value ) {
193
+ $fs_text_overrides[ $slug ][ $key ] = $value;
194
+ }
195
+ }
196
+ }
197
+
198
+ if ( ! function_exists( 'fs_get_ip' ) ) {
199
+ /**
200
+ * Get client IP.
201
+ *
202
+ * @author Vova Feldman (@svovaf)
203
+ * @since 1.1.2
204
+ *
205
+ * @return string|null
206
+ */
207
+ function fs_get_ip() {
208
+ $fields = array(
209
+ 'HTTP_CF_CONNECTING_IP',
210
+ 'HTTP_CLIENT_IP',
211
+ 'HTTP_X_FORWARDED_FOR',
212
+ 'HTTP_X_FORWARDED',
213
+ 'HTTP_FORWARDED_FOR',
214
+ 'HTTP_FORWARDED',
215
+ 'REMOTE_ADDR',
216
+ );
217
+
218
+ foreach ( $fields as $ip_field ) {
219
+ if ( ! empty( $_SERVER[ $ip_field ] ) ) {
220
+ return $_SERVER[ $ip_field ];
221
+ }
222
+ }
223
+
224
+ return null;
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Leverage backtrace to find caller plugin file path.
230
+ *
231
+ * @author Vova Feldman (@svovaf)
232
+ * @since 1.0.6
233
+ *
234
+ * @return string
235
+ */
236
+ function fs_find_caller_plugin_file() {
237
+ /**
238
+ * All the code below will be executed once on activation.
239
+ * If the user changes the main plugin's file name, the file_exists()
240
+ * will catch it.
241
+ */
242
+ if ( ! function_exists( 'get_plugins' ) ) {
243
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
244
+ }
245
+
246
+ $all_plugins = get_plugins();
247
+ $all_plugins_paths = array();
248
+
249
+ // Get active plugin's main files real full names (might be symlinks).
250
+ foreach ( $all_plugins as $relative_path => &$data ) {
251
+ $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
252
+ }
253
+
254
+ $plugin_file = null;
255
+ for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
256
+ if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
257
+ $plugin_file = $bt[ $i ]['file'];
258
+ break;
259
+ }
260
+ }
261
+
262
+ if ( is_null( $plugin_file ) ) {
263
+ // Throw an error to the developer in case of some edge case dev environment.
264
+ wp_die( __fs( 'failed-finding-main-path' ), __fs( 'error' ), array( 'back_link' => true ) );
265
+ }
266
+
267
+ return $plugin_file;
268
+ }
269
+
270
+ /**
271
+ * Update SDK newest version reference.
272
+ *
273
+ * @author Vova Feldman (@svovaf)
274
+ * @since 1.1.6
275
+ *
276
+ * @param string $sdk_relative_path
277
+ * @param string|bool $plugin_file
278
+ *
279
+ * @global $fs_active_plugins
280
+ */
281
+ function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
282
+ global $fs_active_plugins;
283
+
284
+ if ( ! is_string( $plugin_file ) ) {
285
+ $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
286
+ }
287
+
288
+ $fs_active_plugins->newest = (object) array(
289
+ 'plugin_path' => $plugin_file,
290
+ 'sdk_path' => $sdk_relative_path,
291
+ 'version' => $fs_active_plugins->plugins[ $sdk_relative_path ]->version,
292
+ 'in_activation' => ! is_plugin_active( $plugin_file ),
293
+ 'timestamp' => time(),
294
+ );
295
+
296
+ // Update DB with latest SDK version and path.
297
+ update_option( 'fs_active_plugins', $fs_active_plugins );
298
+ }
299
+
300
+ /**
301
+ * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
302
+ *
303
+ * @author Vova Feldman (@svovaf)
304
+ * @since 1.1.6
305
+ *
306
+ * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
307
+ *
308
+ * @global $fs_active_plugins
309
+ */
310
+ function fs_newest_sdk_plugin_first() {
311
+ global $fs_active_plugins;
312
+
313
+ $active_plugins = get_option( 'active_plugins' );
314
+ $newest_sdk_plugin_key = array_search( $fs_active_plugins->newest->plugin_path, $active_plugins );
315
+ if ( 0 == $newest_sdk_plugin_key ) {
316
+ // if it's 0 it's the first plugin already, no need to continue
317
+ return false;
318
+ }
319
+
320
+ array_splice( $active_plugins, $newest_sdk_plugin_key, 1 );
321
+ array_unshift( $active_plugins, $fs_active_plugins->newest->plugin_path );
322
+ update_option( 'active_plugins', $active_plugins );
323
+
324
+ return true;
325
+ }
326
+
327
+ /**
328
+ * Go over all Freemius SDKs in the system and find and "remember"
329
+ * the newest SDK which is associated with an active plugin.
330
+ *
331
+ * @author Vova Feldman (@svovaf)
332
+ * @since 1.1.6
333
+ *
334
+ * @global $fs_active_plugins
335
+ */
336
+ function fs_fallback_to_newest_active_sdk() {
337
+ global $fs_active_plugins;
338
+
339
+ $newest_sdk_data = null;
340
+ $newest_sdk_path = null;
341
+
342
+ foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
343
+ if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
344
+ ) {
345
+ // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
346
+ if ( ! is_plugin_active( $data->plugin_path ) ||
347
+ ! file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) )
348
+ ) {
349
+ unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
350
+
351
+ // No need to store the data since it will be stored in fs_update_sdk_newest_version()
352
+ // or explicitly with update_option().
353
+ } else {
354
+ $newest_sdk_data = $data;
355
+ $newest_sdk_path = $sdk_relative_path;
356
+ }
357
+ }
358
+ }
359
+
360
+ if ( is_null( $newest_sdk_data ) ) {
361
+ // Couldn't find any SDK reference.
362
+ $fs_active_plugins = new stdClass();
363
+ update_option( 'fs_active_plugins', $fs_active_plugins );
364
+ } else {
365
+ fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
366
+ }
367
+ }
368
+
369
+ #region Actions / Filters -----------------------------------------
370
+
371
+ /**
372
+ * Apply filter for specific plugin.
373
+ *
374
+ * @author Vova Feldman (@svovaf)
375
+ * @since 1.0.9
376
+ *
377
+ * @param string $slug Plugin slug
378
+ * @param string $tag The name of the filter hook.
379
+ * @param mixed $value The value on which the filters hooked to `$tag` are applied on.
380
+ *
381
+ * @return mixed The filtered value after all hooked functions are applied to it.
382
+ *
383
+ * @uses apply_filters()
384
+ */
385
+ function fs_apply_filter( $slug, $tag, $value ) {
386
+ $args = func_get_args();
387
+
388
+ return call_user_func_array( 'apply_filters', array_merge(
389
+ array( 'fs_' . $tag . '_' . $slug ),
390
+ array_slice( $args, 2 ) )
391
+ );
392
+ }
393
+
394
+ #endregion Actions / Filters -----------------------------------------
lib/freemius/includes/fs-plugin-functions.php CHANGED
@@ -91,7 +91,6 @@
91
  'changelog' => _x( 'Changelog', 'Plugin installer section title' ),
92
  'reviews' => _x( 'Reviews', 'Plugin installer section title' ),
93
  'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ),
94
- 'features' => __fs( 'features-and-pricing' ),
95
  );
96
 
97
  // Sanitize HTML
@@ -105,6 +104,9 @@
105
  }
106
  }
107
 
 
 
 
108
  $_tab = esc_attr( $tab );
109
 
110
  $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English.
@@ -170,12 +172,12 @@
170
  <?php if ( isset( $api->plans ) ) : ?>
171
  <div class="plugin-information-pricing">
172
  <?php foreach ($api->plans as $plan) : ?>
173
- <h3 data-plan="<?php echo $plan->id ?>"><?php printf( __fs( 'x-plan' ), $plan->title ) ?></h3>
174
  <ul>
175
  <?php $billing_cycle = 'annual' ?>
176
  <?php if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) : ?>
177
  <?php $pricing = $plan->pricing[0] ?>
178
- <li><label><?php _efs( 'price' ) ?>: $<?php
179
  if ( isset( $pricing->annual_price ) ) {
180
  echo $pricing->annual_price . ( $plan->is_block_features ? ' / year' : '' );
181
  $billing_cycle = 'annual';
@@ -194,13 +196,13 @@
194
  value="<?php echo $pricing->id ?>"<?php checked( $first, true ) ?>><?php
195
  switch ( $pricing->licenses ) {
196
  case '1':
197
- _efs( 'license-single-site' );
198
  break;
199
  case null:
200
- _efs( 'license-unlimited' );
201
  break;
202
  default:
203
- printf( __fs( 'license-x-sites' ), $pricing->licenses );
204
  break;
205
  }
206
  ?> - $<?php
@@ -223,7 +225,7 @@
223
  'plan_id' => $plan->id,
224
  'pricing_id' => $plan->pricing[0]->id,
225
  'billing_cycle' => $billing_cycle,
226
- ), $api->checkout_link ) ) . '" target="_parent">' . __fs( 'purchase' ) . '</a>' ?>
227
  </div>
228
  <?php endforeach ?>
229
  <?php wp_enqueue_script( 'jquery' ); ?>
@@ -243,7 +245,7 @@
243
  </script>
244
  <?php endif ?>
245
  <div>
246
- <h3><?php _efs( 'details' ) ?></h3>
247
  <ul>
248
  <?php if ( ! empty( $api->version ) ) { ?>
249
  <li><strong><?php _e( 'Version:' ); ?></strong> <?php echo $api->version; ?></li>
@@ -377,7 +379,7 @@
377
  'plan_id' => $plan->id,
378
  'pricing_id' => $plan->pricing[0]->id,
379
  'billing_cycle' => $billing_cycle,
380
- ), $api->checkout_link ) ) . '" target="_parent">' . __fs( 'purchase' ) . '</a>';
381
 
382
  // @todo Add Cart concept.
383
  // echo ' <a class="button right" href="' . $status['url'] . '" target="_parent">' . __( 'Add to Cart' ) . '</a>';
91
  'changelog' => _x( 'Changelog', 'Plugin installer section title' ),
92
  'reviews' => _x( 'Reviews', 'Plugin installer section title' ),
93
  'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ),
 
94
  );
95
 
96
  // Sanitize HTML
104
  }
105
  }
106
 
107
+ // Add after $api->slug is ready.
108
+ $plugins_section_titles['features'] = __fs( 'features-and-pricing', $api->slug );
109
+
110
  $_tab = esc_attr( $tab );
111
 
112
  $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English.
172
  <?php if ( isset( $api->plans ) ) : ?>
173
  <div class="plugin-information-pricing">
174
  <?php foreach ($api->plans as $plan) : ?>
175
+ <h3 data-plan="<?php echo $plan->id ?>"><?php printf( __fs( 'x-plan', $api->slug ), $plan->title ) ?></h3>
176
  <ul>
177
  <?php $billing_cycle = 'annual' ?>
178
  <?php if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) : ?>
179
  <?php $pricing = $plan->pricing[0] ?>
180
+ <li><label><?php _efs( 'price', $api->slug ) ?>: $<?php
181
  if ( isset( $pricing->annual_price ) ) {
182
  echo $pricing->annual_price . ( $plan->is_block_features ? ' / year' : '' );
183
  $billing_cycle = 'annual';
196
  value="<?php echo $pricing->id ?>"<?php checked( $first, true ) ?>><?php
197
  switch ( $pricing->licenses ) {
198
  case '1':
199
+ _efs( 'license-single-site', $api->slug );
200
  break;
201
  case null:
202
+ _efs( 'license-unlimited', $api->slug );
203
  break;
204
  default:
205
+ printf( __fs( 'license-x-sites', $api->slug ), $pricing->licenses );
206
  break;
207
  }
208
  ?> - $<?php
225
  'plan_id' => $plan->id,
226
  'pricing_id' => $plan->pricing[0]->id,
227
  'billing_cycle' => $billing_cycle,
228
+ ), $api->checkout_link ) ) . '" target="_parent">' . __fs( 'purchase', $api->slug ) . '</a>' ?>
229
  </div>
230
  <?php endforeach ?>
231
  <?php wp_enqueue_script( 'jquery' ); ?>
245
  </script>
246
  <?php endif ?>
247
  <div>
248
+ <h3><?php _efs( 'details', $api->slug ) ?></h3>
249
  <ul>
250
  <?php if ( ! empty( $api->version ) ) { ?>
251
  <li><strong><?php _e( 'Version:' ); ?></strong> <?php echo $api->version; ?></li>
379
  'plan_id' => $plan->id,
380
  'pricing_id' => $plan->pricing[0]->id,
381
  'billing_cycle' => $billing_cycle,
382
+ ), $api->checkout_link ) ) . '" target="_parent">' . __fs( 'purchase', $api->slug ) . '</a>';
383
 
384
  // @todo Add Cart concept.
385
  // echo ' <a class="button right" href="' . $status['url'] . '" target="_parent">' . __( 'Add to Cart' ) . '</a>';
lib/freemius/includes/i18n.php CHANGED
@@ -1,4 +1,34 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  global $fs_text;
3
 
4
  $fs_text = array(
@@ -11,7 +41,7 @@
11
  'add-ons' => __( 'Add Ons', 'freemius' ),
12
  'upgrade' => _x( 'Upgrade', 'verb', 'freemius' ),
13
  'awesome' => __( 'Awesome', 'freemius' ),
14
- 'pricing' => __( 'Pricing', 'noun', 'freemius' ),
15
  'price' => _x( 'Price', 'noun', 'freemius' ),
16
  'unlimited-updates' => __( 'Unlimited Updates', 'freemius' ),
17
  'downgrade' => _x( 'Downgrade', 'verb', 'freemius' ),
@@ -20,7 +50,7 @@
20
  'account-details' => __( 'Account Details', 'freemius' ),
21
  'delete' => _x( 'Delete', 'verb', 'freemius' ),
22
  'delete-account' => __( 'Delete Account', 'freemius' ),
23
- 'dismiss' => __( 'Dismiss', 'as close a window', 'freemius' ),
24
  'plan' => _x( 'Plan', 'as product pricing plan', 'freemius' ),
25
  'change-plan' => __( 'Change Plan', 'freemius' ),
26
  'download-x-version' => _x( 'Download %s Version', 'as download professional version', 'freemius' ),
@@ -34,11 +64,12 @@
34
  'license-single-site' => __( 'Single Site License', 'freemius' ),
35
  'license-unlimited' => __( 'Unlimited Licenses', 'freemius' ),
36
  'license-x-sites' => __( 'Up to %s Sites', 'freemius' ),
 
37
  'x-plan' => _x( '%s Plan', 'e.g. Professional Plan', 'freemius' ),
38
  'you-are-step-away' => __( 'You are just one step away - %s', 'freemius' ),
39
  'activate-x-now' => _x( 'Complete "%s" Activation Now', '%s - plugin name. As complete "Jetpack" activation now', 'freemius' ),
40
  'few-plugin-tweaks' => __( 'We made a few tweaks to the plugin, %s', 'freemius' ),
41
- 'optin-x-now' => __( 'Opt-in to make "%s" Better!', 'freemius' ),
42
  'error' => __( 'Error', 'freemius' ),
43
  'failed-finding-main-path' => __( 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.', 'freemius' ),
44
  #region Account
@@ -56,6 +87,8 @@
56
  'email' => __( 'Email', 'freemius' ),
57
  'verified' => __( 'Verified', 'freemius' ),
58
  'plugin' => __( 'Plugin', 'freemius' ),
 
 
59
  'title' => __( 'Title', 'freemius' ),
60
  'slug' => _x( 'Slug', 'as WP plugin slug', 'freemius' ),
61
  'id' => __( 'ID', 'freemius' ),
@@ -69,10 +102,12 @@
69
  'no-secret' => _x( 'No Secret', 'as secret encryption key missing', 'freemius' ),
70
  'no-id' => __( 'No ID', 'freemius' ),
71
  'sync-license' => _x( 'Sync License', 'as synchronize license', 'freemius' ),
 
72
  'deactivate-license' => __( 'Deactivate License', 'freemius' ),
73
  'activate' => __( 'Activate', 'freemius' ),
74
  'deactivate' => __( 'Deactivate', 'freemius' ),
75
  'active' => _x( 'Active', 'active mode', 'freemius' ),
 
76
  'install-now' => __( 'Install Now', 'freemius' ),
77
  'install-update-now' => __( 'Install Update Now', 'freemius' ),
78
  'more-information-about-x' => __( 'More information about %s', 'freemius' ),
@@ -122,14 +157,17 @@
122
  'hey-x' => _x( 'Hey %s,', 'greeting', 'freemius' ),
123
  'thanks-x' => _x( 'Thanks %s!', 'a greeting. E.g. Thanks John!', 'freemius' ),
124
  'connect-message' => __( 'In order to enjoy all our features and functionality, %s needs to connect your user, %s at %s, to %s', 'freemius' ),
 
125
  'pending-activation-message' => __( 'You should receive an activation email for %s to your mailbox at %s. Please make sure you click the activation button in that email to complete the install.', 'freemius' ),
126
  'what-permissions' => __( 'What permissions are being granted?', 'freemius' ),
127
  'permissions-profile' => __( 'Your Profile Overview', 'freemius' ),
128
  'permissions-profile_desc' => __( 'Name and email address', 'freemius' ),
129
  'permissions-site' => __( 'Your Site Overview', 'freemius' ),
130
- 'permissions-site_desc' => __( 'Site address and WordPress version', 'freemius' ),
131
- 'permissions-events' => __( 'Current Plugin Events', 'freemius' ),
132
  'permissions-events_desc' => __( 'Activation, deactivation and uninstall', 'freemius' ),
 
 
133
  'privacy-policy' => __( 'Privacy Policy', 'freemius' ),
134
  'tos' => __( 'Terms of Service', 'freemius' ),
135
  'activating' => _x( 'Activating', 'as activating plugin', 'freemius' ),
@@ -144,9 +182,23 @@
144
  #endregion Screenshots
145
 
146
  #region Debug
 
 
 
 
 
 
 
 
 
 
 
147
  'addons-of-x' => __( 'Add Ons of Plugin %s', 'freemius' ),
148
  'delete-all-confirm' => __( 'Are you sure you want to delete the all Freemius data?', 'freemius' ),
 
149
  'delete-all-accounts' => __( 'Delete All Accounts', 'freemius' ),
 
 
150
  #endregion Debug
151
 
152
  #region Expressions
@@ -217,12 +269,12 @@
217
  'x-requires-access-to-api' => _x( '%s requires an access to our API.', 'as pluginX requires an access to our API', 'freemius' ),
218
  'squid-blocks-connection-message' => __( 'It looks like your server is using Squid ACL (access control lists), which blocks the connection.', 'freemius' ),
219
  'squid-no-clue-title' => __( 'I don\'t know what is Squid or ACL, help me!', 'freemius' ),
220
- 'squid-no-clue-desc' => __( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.' ),
221
  'sysadmin-title' => __( 'I\'m a system administrator', 'freemius' ),
222
- 'squid-sysadmin-desc' => __( 'Great, please whitelist the following domains: %s. Once you done, deactivate the plugin and activate it again.' ),
223
  'curl-missing-no-clue-title' => __( 'I don\'t know what is cURL or how to install it, help me!', 'freemius' ),
224
- 'curl-missing-no-clue-desc' => __( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.' ),
225
- 'curl-missing-sysadmin-desc' => __( 'Great, please install cURL and enable it in your php.ini file. To make sure it was successfully activated, use \'phpinfo()\'. Once activated, deactivate the plugin and reactivate it back again.' ),
226
  'happy-to-resolve-issue-asap' => __( 'We are sure it\'s an issue on our side and more than happy to resolve it for you ASAP if you give us a chance.', 'freemius' ),
227
  'fix-issue-title' => __( 'Yes - I\'m giving you a chance to fix it', 'freemius' ),
228
  'fix-issue-desc' => __( 'We will do our best to whitelist your server and resolve this issue ASAP. You will get a follow-up email to %s once we have an update.', 'freemius' ),
@@ -231,7 +283,7 @@
231
  'deactivate-plugin-title' => __( 'That\'s exhausting, please deactivate', 'freemius' ),
232
  'deactivate-plugin-desc' => __( 'We feel your frustration and sincerely apologize for the inconvenience. Hope to see you again in the future.', 'freemius' ),
233
  'fix-request-sent-message' => __( 'Thank for giving us the chance to fix it! A message was just sent to our technical staff. We will get back to you as soon as we have an update to %s. Appreciate your patience.', 'freemius' ),
234
- 'server-blocking-access' => _x( 'Your server is blocking the access to Freemius\' API, which is crucial for %1s license synchronization. Please contact your host to whitelist %2s', '%1s - plugin title, %2s - API domain', 'freemius' ),
235
  'wrong-authentication-param-message' => __( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'freemius' ),
236
  #endregion Connectivity Issues
237
  #region Change Owner
@@ -239,7 +291,6 @@
239
  'change-owner-request_owner-confirmed' => __( 'Thanks for confirming the ownership change. An email was just sent to %s for final approval.', 'freemius' ),
240
  'change-owner-request_candidate-confirmed' => __( '%s is the new owner of the account.', 'freemius' ),
241
  #endregion Change Owner
242
- 'freemius-debug' => __( 'Freemius Debug', 'freemius' ),
243
  'addon-x-cannot-run-without-y' => _x( '%s cannot run without %s.', 'addonX cannot run without pluginY', 'freemius' ),
244
  'addon-x-cannot-run-without-parent' => _x( '%s cannot run without the plugin.', 'addonX cannot run...', 'freemius' ),
245
  'plugin-x-activation-message' => _x( '%s activation was successfully completed.', 'pluginX activation was successfully...', 'freemius' ),
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.1.4
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * All strings can now be overridden.
15
+ *
16
+ * For example, if we want to override:
17
+ * 'you-are-step-away' => 'You are just one step away - %s',
18
+ *
19
+ * We can use the filter:
20
+ * fs_override_i18n( array(
21
+ * 'opt-in-connect' => __( "Yes - I'm in!", '{your-text_domain}' ),
22
+ * 'skip' => __( 'Not today', '{your-text_domain}' ),
23
+ * ), '{plugin_slug}' );
24
+ *
25
+ * Or with the Freemius instance:
26
+ *
27
+ * my_freemius->override_i18n( array(
28
+ * 'opt-in-connect' => __( "Yes - I'm in!", '{your-text_domain}' ),
29
+ * 'skip' => __( 'Not today', '{your-text_domain}' ),
30
+ * );
31
+ */
32
  global $fs_text;
33
 
34
  $fs_text = array(
41
  'add-ons' => __( 'Add Ons', 'freemius' ),
42
  'upgrade' => _x( 'Upgrade', 'verb', 'freemius' ),
43
  'awesome' => __( 'Awesome', 'freemius' ),
44
+ 'pricing' => _x( 'Pricing', 'noun', 'freemius' ),
45
  'price' => _x( 'Price', 'noun', 'freemius' ),
46
  'unlimited-updates' => __( 'Unlimited Updates', 'freemius' ),
47
  'downgrade' => _x( 'Downgrade', 'verb', 'freemius' ),
50
  'account-details' => __( 'Account Details', 'freemius' ),
51
  'delete' => _x( 'Delete', 'verb', 'freemius' ),
52
  'delete-account' => __( 'Delete Account', 'freemius' ),
53
+ 'dismiss' => _x( 'Dismiss', 'as close a window', 'freemius' ),
54
  'plan' => _x( 'Plan', 'as product pricing plan', 'freemius' ),
55
  'change-plan' => __( 'Change Plan', 'freemius' ),
56
  'download-x-version' => _x( 'Download %s Version', 'as download professional version', 'freemius' ),
64
  'license-single-site' => __( 'Single Site License', 'freemius' ),
65
  'license-unlimited' => __( 'Unlimited Licenses', 'freemius' ),
66
  'license-x-sites' => __( 'Up to %s Sites', 'freemius' ),
67
+ 'renew-license-now' => __( '%sRenew your license now%s to access version %s features and support.', 'freemius' ),
68
  'x-plan' => _x( '%s Plan', 'e.g. Professional Plan', 'freemius' ),
69
  'you-are-step-away' => __( 'You are just one step away - %s', 'freemius' ),
70
  'activate-x-now' => _x( 'Complete "%s" Activation Now', '%s - plugin name. As complete "Jetpack" activation now', 'freemius' ),
71
  'few-plugin-tweaks' => __( 'We made a few tweaks to the plugin, %s', 'freemius' ),
72
+ 'optin-x-now' => __( 'Opt-in to make "%s" Better!', 'freemius' ),
73
  'error' => __( 'Error', 'freemius' ),
74
  'failed-finding-main-path' => __( 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.', 'freemius' ),
75
  #region Account
87
  'email' => __( 'Email', 'freemius' ),
88
  'verified' => __( 'Verified', 'freemius' ),
89
  'plugin' => __( 'Plugin', 'freemius' ),
90
+ 'plugins' => __( 'Plugins', 'freemius' ),
91
+ 'path' => _x( 'Path', 'as file/folder path', 'freemius' ),
92
  'title' => __( 'Title', 'freemius' ),
93
  'slug' => _x( 'Slug', 'as WP plugin slug', 'freemius' ),
94
  'id' => __( 'ID', 'freemius' ),
102
  'no-secret' => _x( 'No Secret', 'as secret encryption key missing', 'freemius' ),
103
  'no-id' => __( 'No ID', 'freemius' ),
104
  'sync-license' => _x( 'Sync License', 'as synchronize license', 'freemius' ),
105
+ 'sync' => _x( 'Sync', 'as synchronize', 'freemius' ),
106
  'deactivate-license' => __( 'Deactivate License', 'freemius' ),
107
  'activate' => __( 'Activate', 'freemius' ),
108
  'deactivate' => __( 'Deactivate', 'freemius' ),
109
  'active' => _x( 'Active', 'active mode', 'freemius' ),
110
+ 'is-active' => _x( 'Is Active', 'is active mode?', 'freemius' ),
111
  'install-now' => __( 'Install Now', 'freemius' ),
112
  'install-update-now' => __( 'Install Update Now', 'freemius' ),
113
  'more-information-about-x' => __( 'More information about %s', 'freemius' ),
157
  'hey-x' => _x( 'Hey %s,', 'greeting', 'freemius' ),
158
  'thanks-x' => _x( 'Thanks %s!', 'a greeting. E.g. Thanks John!', 'freemius' ),
159
  'connect-message' => __( 'In order to enjoy all our features and functionality, %s needs to connect your user, %s at %s, to %s', 'freemius' ),
160
+ 'connect-message_on-update' => __( 'Please help us improve %2$s! If you opt-in, some data about your usage of %2$s will be sent to %5$s. If you skip this, that\'s okay! %2$s will still work just fine.', 'freemius' ),
161
  'pending-activation-message' => __( 'You should receive an activation email for %s to your mailbox at %s. Please make sure you click the activation button in that email to complete the install.', 'freemius' ),
162
  'what-permissions' => __( 'What permissions are being granted?', 'freemius' ),
163
  'permissions-profile' => __( 'Your Profile Overview', 'freemius' ),
164
  'permissions-profile_desc' => __( 'Name and email address', 'freemius' ),
165
  'permissions-site' => __( 'Your Site Overview', 'freemius' ),
166
+ 'permissions-site_desc' => __( 'Site address, WordPress version, PHP Version', 'freemius' ),
167
+ 'permissions-events' => __( 'Plugin Events', 'freemius' ),
168
  'permissions-events_desc' => __( 'Activation, deactivation and uninstall', 'freemius' ),
169
+ 'permissions-newsletter' => __( 'Newsletter', 'freemius' ),
170
+ 'permissions-newsletter_desc' => __( 'Updates, announcements, marketing, no spam', 'freemius' ),
171
  'privacy-policy' => __( 'Privacy Policy', 'freemius' ),
172
  'tos' => __( 'Terms of Service', 'freemius' ),
173
  'activating' => _x( 'Activating', 'as activating plugin', 'freemius' ),
182
  #endregion Screenshots
183
 
184
  #region Debug
185
+ 'freemius-debug' => __( 'Freemius Debug', 'freemius' ),
186
+ 'on' => _x( 'On', 'as turned on', 'freemius' ),
187
+ 'off' => _x( 'Off', 'as turned off', 'freemius' ),
188
+ 'freemius-state' => __( 'Freemius State', 'freemius' ),
189
+ 'connected' => _x( 'Connected', 'as connection was successful', 'freemius' ),
190
+ 'blocked' => _x( 'Blocked', 'as connection blocked', 'freemius' ),
191
+ 'api' => _x( 'API', 'as application program interface', 'freemius' ),
192
+ 'sdk' => _x( 'SDK', 'as software development kit versions', 'freemius' ),
193
+ 'sdk-versions' => _x( 'SDK Versions', 'as software development kit versions', 'freemius' ),
194
+ 'plugin-path' => _x( 'Plugin Path', 'as plugin folder path', 'freemius' ),
195
+ 'sdk-path' => _x( 'SDK Path', 'as sdk path', 'freemius' ),
196
  'addons-of-x' => __( 'Add Ons of Plugin %s', 'freemius' ),
197
  'delete-all-confirm' => __( 'Are you sure you want to delete the all Freemius data?', 'freemius' ),
198
+ 'actions' => __( 'Actions', 'freemius' ),
199
  'delete-all-accounts' => __( 'Delete All Accounts', 'freemius' ),
200
+ 'clear-api-cache' => __( 'Clear API Cache', 'freemius' ),
201
+ 'sync-data-from-server' => __( 'Sync Data From Server', 'freemius' ),
202
  #endregion Debug
203
 
204
  #region Expressions
269
  'x-requires-access-to-api' => _x( '%s requires an access to our API.', 'as pluginX requires an access to our API', 'freemius' ),
270
  'squid-blocks-connection-message' => __( 'It looks like your server is using Squid ACL (access control lists), which blocks the connection.', 'freemius' ),
271
  'squid-no-clue-title' => __( 'I don\'t know what is Squid or ACL, help me!', 'freemius' ),
272
+ 'squid-no-clue-desc' => __( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.', 'freemius' ),
273
  'sysadmin-title' => __( 'I\'m a system administrator', 'freemius' ),
274
+ 'squid-sysadmin-desc' => __( 'Great, please whitelist the following domains: %s. Once you done, deactivate the plugin and activate it again.', 'freemius' ),
275
  'curl-missing-no-clue-title' => __( 'I don\'t know what is cURL or how to install it, help me!', 'freemius' ),
276
+ 'curl-missing-no-clue-desc' => __( 'We\'ll make sure to contact your hosting company and resolve the issue. You will get a follow-up email to %s once we have an update.', 'freemius' ),
277
+ 'curl-missing-sysadmin-desc' => __( 'Great, please install cURL and enable it in your php.ini file. To make sure it was successfully activated, use \'phpinfo()\'. Once activated, deactivate the plugin and reactivate it back again.', 'freemius' ),
278
  'happy-to-resolve-issue-asap' => __( 'We are sure it\'s an issue on our side and more than happy to resolve it for you ASAP if you give us a chance.', 'freemius' ),
279
  'fix-issue-title' => __( 'Yes - I\'m giving you a chance to fix it', 'freemius' ),
280
  'fix-issue-desc' => __( 'We will do our best to whitelist your server and resolve this issue ASAP. You will get a follow-up email to %s once we have an update.', 'freemius' ),
283
  'deactivate-plugin-title' => __( 'That\'s exhausting, please deactivate', 'freemius' ),
284
  'deactivate-plugin-desc' => __( 'We feel your frustration and sincerely apologize for the inconvenience. Hope to see you again in the future.', 'freemius' ),
285
  'fix-request-sent-message' => __( 'Thank for giving us the chance to fix it! A message was just sent to our technical staff. We will get back to you as soon as we have an update to %s. Appreciate your patience.', 'freemius' ),
286
+ 'server-blocking-access' => _x( 'Your server is blocking the access to Freemius\' API, which is crucial for %1s synchronization. Please contact your host to whitelist %2s', '%1s - plugin title, %2s - API domain', 'freemius' ),
287
  'wrong-authentication-param-message' => __( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'freemius' ),
288
  #endregion Connectivity Issues
289
  #region Change Owner
291
  'change-owner-request_owner-confirmed' => __( 'Thanks for confirming the ownership change. An email was just sent to %s for final approval.', 'freemius' ),
292
  'change-owner-request_candidate-confirmed' => __( '%s is the new owner of the account.', 'freemius' ),
293
  #endregion Change Owner
 
294
  'addon-x-cannot-run-without-y' => _x( '%s cannot run without %s.', 'addonX cannot run without pluginY', 'freemius' ),
295
  'addon-x-cannot-run-without-parent' => _x( '%s cannot run without the plugin.', 'addonX cannot run...', 'freemius' ),
296
  'plugin-x-activation-message' => _x( '%s activation was successfully completed.', 'pluginX activation was successfully...', 'freemius' ),
lib/freemius/includes/managers/class-fs-admin-menu-manager.php CHANGED
@@ -110,7 +110,7 @@
110
  }
111
 
112
  private function get_bool_option( &$options, $key, $default = false ) {
113
- return isset( $options[ $key ] ) && is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
114
  }
115
 
116
  #endregion Helpers
@@ -239,7 +239,12 @@
239
  * @return bool
240
  */
241
  function is_submenu_item_visible( $id, $default = true ) {
242
- return $this->get_bool_option( $this->_default_submenu_items, $id, $default );
 
 
 
 
 
243
  }
244
 
245
  /**
110
  }
111
 
112
  private function get_bool_option( &$options, $key, $default = false ) {
113
+ return isset( $options[ $key ] ) &&is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
114
  }
115
 
116
  #endregion Helpers
239
  * @return bool
240
  */
241
  function is_submenu_item_visible( $id, $default = true ) {
242
+ return fs_apply_filter(
243
+ $this->_plugin_slug,
244
+ 'is_submenu_visible',
245
+ $this->get_bool_option( $this->_default_submenu_items, $id, $default ),
246
+ $id
247
+ );
248
  }
249
 
250
  /**
lib/freemius/includes/managers/class-fs-cache-manager.php ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.1.6
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class FS_Cache_Manager {
14
+ /**
15
+ * @var FS_Option_Manager
16
+ */
17
+ private $_options;
18
+ /**
19
+ * @var FS_Logger
20
+ */
21
+ private $_logger;
22
+
23
+ /**
24
+ * @var FS_Cache_Manager[]
25
+ */
26
+ private static $_MANAGERS = array();
27
+
28
+ /**
29
+ * @author Vova Feldman (@svovaf)
30
+ * @since 1.1.3
31
+ *
32
+ * @param string $id
33
+ */
34
+ private function __construct( $id ) {
35
+ $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_cach_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
36
+
37
+ $this->_logger->entrance();
38
+ $this->_logger->log( 'id = ' . $id );
39
+
40
+ $this->_options = FS_Option_Manager::get_manager( $id, true );
41
+ }
42
+
43
+ /**
44
+ * @author Vova Feldman (@svovaf)
45
+ * @since 1.1.6
46
+ *
47
+ * @param $id
48
+ *
49
+ * @return FS_Cache_Manager
50
+ */
51
+ static function get_manager( $id ) {
52
+ $id = strtolower( $id );
53
+
54
+ if ( ! isset( self::$_MANAGERS[ $id ] ) ) {
55
+ self::$_MANAGERS[ $id ] = new FS_Cache_Manager( $id );
56
+ }
57
+
58
+ return self::$_MANAGERS[ $id ];
59
+ }
60
+
61
+ /**
62
+ * @author Vova Feldman (@svovaf)
63
+ * @since 1.1.6
64
+ *
65
+ * @return bool
66
+ */
67
+ function is_empty() {
68
+ $this->_logger->entrance();
69
+
70
+ return $this->_options->is_empty();
71
+ }
72
+
73
+ /**
74
+ * @author Vova Feldman (@svovaf)
75
+ * @since 1.1.6
76
+ */
77
+ function clear() {
78
+ $this->_logger->entrance();
79
+
80
+ $this->_options->clear( true );
81
+ }
82
+
83
+ /**
84
+ * Delete cache manager from DB.
85
+ *
86
+ * @author Vova Feldman (@svovaf)
87
+ * @since 1.0.9
88
+ */
89
+ function delete() {
90
+ $this->_options->delete();
91
+ }
92
+
93
+ /**
94
+ * Check if there's a cached item.
95
+ *
96
+ * @author Vova Feldman (@svovaf)
97
+ * @since 1.1.6
98
+ *
99
+ * @param string $key
100
+ *
101
+ * @return bool
102
+ */
103
+ function has( $key ) {
104
+ $cache_entry = $this->_options->get_option( $key, false );
105
+
106
+ return ( is_object( $cache_entry ) &&
107
+ isset( $cache_entry->timestamp ) &&
108
+ is_numeric( $cache_entry->timestamp )
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Check if there's a valid cached item.
114
+ *
115
+ * @author Vova Feldman (@svovaf)
116
+ * @since 1.1.6
117
+ *
118
+ * @param string $key
119
+ *
120
+ * @return bool
121
+ */
122
+ function has_valid( $key ) {
123
+ $cache_entry = $this->_options->get_option( $key, false );
124
+
125
+ return ( is_object( $cache_entry ) &&
126
+ isset( $cache_entry->timestamp ) &&
127
+ is_numeric( $cache_entry->timestamp ) &&
128
+ $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
129
+ );
130
+ }
131
+
132
+ /**
133
+ * @author Vova Feldman (@svovaf)
134
+ * @since 1.1.6
135
+ *
136
+ * @param string $key
137
+ * @param mixed $default
138
+ *
139
+ * @return mixed
140
+ */
141
+ function get( $key, $default = null ) {
142
+ $this->_logger->entrance( 'key = ' . $key );
143
+
144
+ $cache_entry = $this->_options->get_option( $key, false );
145
+
146
+ if ( is_object( $cache_entry ) &&
147
+ isset( $cache_entry->timestamp ) &&
148
+ is_numeric( $cache_entry->timestamp )
149
+ ) {
150
+ return $cache_entry->result;
151
+ }
152
+
153
+ return $default;
154
+ }
155
+
156
+ /**
157
+ * @author Vova Feldman (@svovaf)
158
+ * @since 1.1.6
159
+ *
160
+ * @param string $key
161
+ * @param mixed $default
162
+ *
163
+ * @return mixed
164
+ */
165
+ function get_valid( $key, $default = null ) {
166
+ $this->_logger->entrance( 'key = ' . $key );
167
+
168
+ $cache_entry = $this->_options->get_option( $key, false );
169
+
170
+ if ( is_object( $cache_entry ) &&
171
+ isset( $cache_entry->timestamp ) &&
172
+ is_numeric( $cache_entry->timestamp ) &&
173
+ $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME
174
+ ) {
175
+ return $cache_entry->result;
176
+ }
177
+
178
+ return $default;
179
+ }
180
+
181
+ /**
182
+ * @author Vova Feldman (@svovaf)
183
+ * @since 1.1.6
184
+ *
185
+ * @param string $key
186
+ * @param mixed $value
187
+ * @param int $expiration
188
+ */
189
+ function set( $key, $value, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) {
190
+ $this->_logger->entrance( 'key = ' . $key );
191
+
192
+ $cache_entry = new stdClass();
193
+ $cache_entry->result = $value;
194
+ $cache_entry->timestamp = WP_FS__SCRIPT_START_TIME + $expiration;
195
+ $this->_options->set_option( $key, $cache_entry, true );
196
+ }
197
+
198
+ /**
199
+ * Purge cached item.
200
+ *
201
+ * @author Vova Feldman (@svovaf)
202
+ * @since 1.1.6
203
+ *
204
+ * @param string $key
205
+ */
206
+ function purge( $key ) {
207
+ $this->_logger->entrance( 'key = ' . $key );
208
+
209
+ $this->_options->unset_option( $key, true );
210
+ }
211
+ }
lib/freemius/includes/sdk/Exceptions/ArgumentNotExistException.php CHANGED
@@ -1,2 +1,6 @@
1
  <?php
 
 
 
 
2
  class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException { }
1
  <?php
2
+ if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
3
+ exit;
4
+ }
5
+
6
  class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException { }
lib/freemius/includes/sdk/Exceptions/EmptyArgumentException.php CHANGED
@@ -1,2 +1,6 @@
1
  <?php
 
 
 
 
2
  class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException { }
1
  <?php
2
+ if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
3
+ exit;
4
+ }
5
+
6
  class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException { }
lib/freemius/includes/sdk/Exceptions/InvalidArgumentException.php CHANGED
@@ -1,2 +1,6 @@
1
  <?php
 
 
 
 
2
  class Freemius_InvalidArgumentException extends Freemius_Exception { }
1
  <?php
2
+ if ( ! class_exists( 'Freemius_Exception' ) ) {
3
+ exit;
4
+ }
5
+
6
  class Freemius_InvalidArgumentException extends Freemius_Exception { }
lib/freemius/includes/sdk/Exceptions/OAuthException.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php
 
 
 
 
2
  class Freemius_OAuthException extends Freemius_Exception
3
  {
4
  public function __construct($pResult)
1
  <?php
2
+ if ( ! class_exists( 'Freemius_Exception' ) ) {
3
+ exit;
4
+ }
5
+
6
  class Freemius_OAuthException extends Freemius_Exception
7
  {
8
  public function __construct($pResult)
lib/freemius/includes/sdk/Freemius.php CHANGED
@@ -75,8 +75,8 @@
75
  parent::Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox );
76
  }
77
 
78
- public function GetUrl( $pCanonizedPath = '' ) {
79
- $address = ( $this->_sandbox ? FS_API__SANDBOX_ADDRESS : FS_API__ADDRESS );
80
 
81
  if ( ':' === $address[0] ) {
82
  $address = self::$_protocol . $address;
@@ -85,6 +85,8 @@
85
  return $address . $pCanonizedPath;
86
  }
87
 
 
 
88
  /**
89
  * @var int Clock diff in seconds between current server to API server.
90
  */
@@ -101,6 +103,21 @@
101
  self::$_clock_diff = $pSeconds;
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  /**
105
  * @var string http or https
106
  */
@@ -132,25 +149,27 @@
132
  * {scope_entity_secret_key}))
133
  *
134
  * @param string $pResourceUrl
135
- * @param array $opts
 
 
136
  */
137
- protected function SignRequest( $pResourceUrl, &$opts ) {
138
  $eol = "\n";
139
  $content_md5 = '';
140
  $now = ( time() - self::$_clock_diff );
141
  $date = date( 'r', $now );
142
  $content_type = '';
143
 
144
- if ( isset( $opts[ CURLOPT_POST ] ) && 0 < $opts[ CURLOPT_POST ] ) {
145
- $content_md5 = md5( $opts[ CURLOPT_POSTFIELDS ] );
146
- $opts[ CURLOPT_HTTPHEADER ][] = 'Content-MD5: ' . $content_md5;
147
- $content_type = 'application/json';
148
  }
149
 
150
- $opts[ CURLOPT_HTTPHEADER ][] = 'Date: ' . $date;
151
 
152
  $string_to_sign = implode( $eol, array(
153
- $opts[ CURLOPT_CUSTOMREQUEST ],
154
  $content_md5,
155
  $content_type,
156
  $date,
@@ -162,13 +181,15 @@
162
  $auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
163
 
164
  // Add authorization header.
165
- $opts[ CURLOPT_HTTPHEADER ][] = 'Authorization: ' .
166
- $auth_type . ' ' .
167
- $this->_id . ':' .
168
- $this->_public . ':' .
169
- self::Base64UrlEncode(
170
- hash_hmac( 'sha256', $string_to_sign, $this->_secret )
171
- );
 
 
172
  }
173
 
174
  /**
@@ -202,7 +223,7 @@
202
  // the signature uses public key hash encoding.
203
  $auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
204
 
205
- return $this->GetUrl(
206
  $pResourceUrl . '?' .
207
  ( 1 < count( $resource ) && ! empty( $resource[1] ) ? $resource[1] . '&' : '' ) .
208
  http_build_query( array(
@@ -212,37 +233,42 @@
212
  self::Base64UrlEncode( hash_hmac(
213
  'sha256', $string_to_sign, $this->_secret
214
  ) )
215
- ) ) );
216
  }
217
 
218
  /**
219
- * Makes an HTTP request. This method can be overridden by subclasses if
220
- * developers want to do fancier things or use something other than curl to
221
- * make the request.
222
- *
223
- * @param string $pCanonizedPath The URL to make the request to
224
- * @param string $pMethod HTTP method
225
- * @param array $params The parameters to use for the POST body
226
- * @param null|resource $ch Initialized curl handle
227
  *
228
  * @return object[]|object|null
229
  *
230
- * @throws Freemius_Exception
231
  */
232
- public function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $params = array(), $ch = null ) {
233
- if ( !FS_SDK__HAS_CURL ) {
234
- $this->ThrowNoCurlException();
 
 
 
 
 
 
 
235
  }
236
 
237
  // Connectivity errors simulation.
238
  if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE ) {
239
- $this->ThrowCloudFlareDDoSException();
240
  } else if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL ) {
241
- $this->ThrowSquidAclException();
242
  }
243
 
244
- if ( ! $ch ) {
245
- $ch = curl_init();
246
  }
247
 
248
  $opts = self::$CURL_OPTS;
@@ -252,25 +278,20 @@
252
  }
253
 
254
  if ( 'POST' === $pMethod || 'PUT' === $pMethod ) {
255
- if ( is_array( $params ) && 0 < count( $params ) ) {
256
  $opts[ CURLOPT_HTTPHEADER ][] = 'Content-Type: application/json';
257
- $opts[ CURLOPT_POST ] = count( $params );
258
- $opts[ CURLOPT_POSTFIELDS ] = json_encode( $params );
259
  }
260
 
261
  $opts[ CURLOPT_RETURNTRANSFER ] = true;
262
  }
263
 
264
- $opts[ CURLOPT_URL ] = $this->GetUrl( $pCanonizedPath );
265
  $opts[ CURLOPT_CUSTOMREQUEST ] = $pMethod;
266
 
267
  $resource = explode( '?', $pCanonizedPath );
268
 
269
- // Only sign request if not ping.json connectivity test.
270
- if ( '/v1/ping.json' !== strtolower( substr( $resource[0], - strlen( '/v1/ping.json' ) ) ) ) {
271
- $this->SignRequest( $resource[0], $opts );
272
- }
273
-
274
  // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
275
  // for 2 seconds if the server does not support this header.
276
  $opts[ CURLOPT_HTTPHEADER ][] = 'Expect:';
@@ -280,8 +301,14 @@
280
  $opts[ CURLOPT_SSL_VERIFYPEER ] = false;
281
  }
282
 
283
- curl_setopt_array( $ch, $opts );
284
- $result = curl_exec( $ch );
 
 
 
 
 
 
285
 
286
  /*if (curl_errno($ch) == 60) // CURLE_SSL_CACERT
287
  {
@@ -299,33 +326,25 @@
299
  if ( false === $result && empty( $opts[ CURLOPT_IPRESOLVE ] ) ) {
300
  $matches = array();
301
  $regex = '/Failed to connect to ([^:].*): Network is unreachable/';
302
- if ( preg_match( $regex, curl_error( $ch ), $matches ) ) {
303
  if ( strlen( @inet_pton( $matches[1] ) ) === 16 ) {
304
  // self::errorLog('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
305
  self::$CURL_OPTS[ CURLOPT_IPRESOLVE ] = CURL_IPRESOLVE_V4;
306
- curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
307
- $result = curl_exec( $ch );
308
  }
309
  }
310
  }
311
 
312
  if ( $result === false ) {
313
- $e = new Freemius_Exception( array(
314
- 'error' => array(
315
- 'code' => curl_errno( $ch ),
316
- 'message' => curl_error( $ch ),
317
- 'type' => 'CurlException',
318
- ),
319
- ) );
320
-
321
- curl_close( $ch );
322
- throw $e;
323
  }
324
 
325
- curl_close( $ch );
326
 
327
- if (empty($result))
328
  return null;
 
329
 
330
  $decoded = json_decode( $result );
331
 
@@ -333,11 +352,11 @@
333
  if ( preg_match( '/Please turn JavaScript on/i', $result ) &&
334
  preg_match( '/text\/javascript/', $result )
335
  ) {
336
- $this->ThrowCloudFlareDDoSException( $result );
337
  } else if ( preg_match( '/Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect./', $result ) &&
338
  preg_match( '/squid/', $result )
339
  ) {
340
- $this->ThrowSquidAclException( $result );
341
  } else {
342
  $decoded = (object) array(
343
  'error' => (object) array(
@@ -353,12 +372,121 @@
353
  return $decoded;
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  /**
357
  * @param string $pResult
358
  *
359
  * @throws Freemius_Exception
360
  */
361
- private function ThrowNoCurlException( $pResult = '' ) {
362
  throw new Freemius_Exception( array(
363
  'error' => (object) array(
364
  'type' => 'cUrlMissing',
@@ -374,7 +502,7 @@
374
  *
375
  * @throws Freemius_Exception
376
  */
377
- private function ThrowCloudFlareDDoSException( $pResult = '' ) {
378
  throw new Freemius_Exception( array(
379
  'error' => (object) array(
380
  'type' => 'CloudFlareDDoSProtection',
@@ -390,7 +518,7 @@
390
  *
391
  * @throws Freemius_Exception
392
  */
393
- private function ThrowSquidAclException( $pResult = '' ) {
394
  throw new Freemius_Exception( array(
395
  'error' => (object) array(
396
  'type' => 'SquidCacheBlock',
@@ -400,4 +528,6 @@
400
  )
401
  ) );
402
  }
 
 
403
  }
75
  parent::Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox );
76
  }
77
 
78
+ public static function GetUrl( $pCanonizedPath = '', $pIsSandbox = false ) {
79
+ $address = ( $pIsSandbox ? FS_API__SANDBOX_ADDRESS : FS_API__ADDRESS );
80
 
81
  if ( ':' === $address[0] ) {
82
  $address = self::$_protocol . $address;
85
  return $address . $pCanonizedPath;
86
  }
87
 
88
+ #region Servers Clock Diff ------------------------------------------------------
89
+
90
  /**
91
  * @var int Clock diff in seconds between current server to API server.
92
  */
103
  self::$_clock_diff = $pSeconds;
104
  }
105
 
106
+ /**
107
+ * Find clock diff between current server to API server.
108
+ *
109
+ * @since 1.0.2
110
+ * @return int Clock diff in seconds.
111
+ */
112
+ public static function FindClockDiff() {
113
+ $time = time();
114
+ $pong = self::Ping();
115
+
116
+ return ( $time - strtotime( $pong->timestamp ) );
117
+ }
118
+
119
+ #endregion Servers Clock Diff ------------------------------------------------------
120
+
121
  /**
122
  * @var string http or https
123
  */
149
  * {scope_entity_secret_key}))
150
  *
151
  * @param string $pResourceUrl
152
+ * @param array $pCurlOptions
153
+ *
154
+ * @return array
155
  */
156
+ function SignRequest( $pResourceUrl, $pCurlOptions ) {
157
  $eol = "\n";
158
  $content_md5 = '';
159
  $now = ( time() - self::$_clock_diff );
160
  $date = date( 'r', $now );
161
  $content_type = '';
162
 
163
+ if ( isset( $pCurlOptions[ CURLOPT_POST ] ) && 0 < $pCurlOptions[ CURLOPT_POST ] ) {
164
+ $content_md5 = md5( $pCurlOptions[ CURLOPT_POSTFIELDS ] );
165
+ $pCurlOptions[ CURLOPT_HTTPHEADER ][] = 'Content-MD5: ' . $content_md5;
166
+ $content_type = 'application/json';
167
  }
168
 
169
+ $pCurlOptions[ CURLOPT_HTTPHEADER ][] = 'Date: ' . $date;
170
 
171
  $string_to_sign = implode( $eol, array(
172
+ $pCurlOptions[ CURLOPT_CUSTOMREQUEST ],
173
  $content_md5,
174
  $content_type,
175
  $date,
181
  $auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
182
 
183
  // Add authorization header.
184
+ $pCurlOptions[ CURLOPT_HTTPHEADER ][] = 'Authorization: ' .
185
+ $auth_type . ' ' .
186
+ $this->_id . ':' .
187
+ $this->_public . ':' .
188
+ self::Base64UrlEncode(
189
+ hash_hmac( 'sha256', $string_to_sign, $this->_secret )
190
+ );
191
+
192
+ return $pCurlOptions;
193
  }
194
 
195
  /**
223
  // the signature uses public key hash encoding.
224
  $auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
225
 
226
+ return Freemius_Api::GetUrl(
227
  $pResourceUrl . '?' .
228
  ( 1 < count( $resource ) && ! empty( $resource[1] ) ? $resource[1] . '&' : '' ) .
229
  http_build_query( array(
233
  self::Base64UrlEncode( hash_hmac(
234
  'sha256', $string_to_sign, $this->_secret
235
  ) )
236
+ ) ), $this->_isSandbox );
237
  }
238
 
239
  /**
240
+ * @param string $pCanonizedPath
241
+ * @param string $pMethod
242
+ * @param array $pParams
243
+ * @param null|resource $pCurlHandler
244
+ * @param bool $pIsSandbox
245
+ * @param null|callable $pBeforeExecutionFunction
 
 
246
  *
247
  * @return object[]|object|null
248
  *
249
+ * @throws \Freemius_Exception
250
  */
251
+ private static function MakeStaticRequest(
252
+ $pCanonizedPath,
253
+ $pMethod = 'GET',
254
+ $pParams = array(),
255
+ $pCurlHandler = null,
256
+ $pIsSandbox = false,
257
+ $pBeforeExecutionFunction = null
258
+ ) {
259
+ if ( ! FS_SDK__HAS_CURL ) {
260
+ self::ThrowNoCurlException();
261
  }
262
 
263
  // Connectivity errors simulation.
264
  if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE ) {
265
+ self::ThrowCloudFlareDDoSException();
266
  } else if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL ) {
267
+ self::ThrowSquidAclException();
268
  }
269
 
270
+ if ( ! $pCurlHandler ) {
271
+ $pCurlHandler = curl_init();
272
  }
273
 
274
  $opts = self::$CURL_OPTS;
278
  }
279
 
280
  if ( 'POST' === $pMethod || 'PUT' === $pMethod ) {
281
+ if ( is_array( $pParams ) && 0 < count( $pParams ) ) {
282
  $opts[ CURLOPT_HTTPHEADER ][] = 'Content-Type: application/json';
283
+ $opts[ CURLOPT_POST ] = count( $pParams );
284
+ $opts[ CURLOPT_POSTFIELDS ] = json_encode( $pParams );
285
  }
286
 
287
  $opts[ CURLOPT_RETURNTRANSFER ] = true;
288
  }
289
 
290
+ $opts[ CURLOPT_URL ] = Freemius_Api::GetUrl( $pCanonizedPath, $pIsSandbox );
291
  $opts[ CURLOPT_CUSTOMREQUEST ] = $pMethod;
292
 
293
  $resource = explode( '?', $pCanonizedPath );
294
 
 
 
 
 
 
295
  // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
296
  // for 2 seconds if the server does not support this header.
297
  $opts[ CURLOPT_HTTPHEADER ][] = 'Expect:';
301
  $opts[ CURLOPT_SSL_VERIFYPEER ] = false;
302
  }
303
 
304
+ if ( false !== $pBeforeExecutionFunction &&
305
+ is_callable( $pBeforeExecutionFunction )
306
+ ) {
307
+ $opts = call_user_func( $pBeforeExecutionFunction, $resource[0], $opts );
308
+ }
309
+
310
+ curl_setopt_array( $pCurlHandler, $opts );
311
+ $result = curl_exec( $pCurlHandler );
312
 
313
  /*if (curl_errno($ch) == 60) // CURLE_SSL_CACERT
314
  {
326
  if ( false === $result && empty( $opts[ CURLOPT_IPRESOLVE ] ) ) {
327
  $matches = array();
328
  $regex = '/Failed to connect to ([^:].*): Network is unreachable/';
329
+ if ( preg_match( $regex, curl_error( $pCurlHandler ), $matches ) ) {
330
  if ( strlen( @inet_pton( $matches[1] ) ) === 16 ) {
331
  // self::errorLog('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
332
  self::$CURL_OPTS[ CURLOPT_IPRESOLVE ] = CURL_IPRESOLVE_V4;
333
+ curl_setopt( $pCurlHandler, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
334
+ $result = curl_exec( $pCurlHandler );
335
  }
336
  }
337
  }
338
 
339
  if ( $result === false ) {
340
+ self::ThrowCurlException( $pCurlHandler );
 
 
 
 
 
 
 
 
 
341
  }
342
 
343
+ curl_close( $pCurlHandler );
344
 
345
+ if ( empty( $result ) ) {
346
  return null;
347
+ }
348
 
349
  $decoded = json_decode( $result );
350
 
352
  if ( preg_match( '/Please turn JavaScript on/i', $result ) &&
353
  preg_match( '/text\/javascript/', $result )
354
  ) {
355
+ self::ThrowCloudFlareDDoSException( $result );
356
  } else if ( preg_match( '/Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect./', $result ) &&
357
  preg_match( '/squid/', $result )
358
  ) {
359
+ self::ThrowSquidAclException( $result );
360
  } else {
361
  $decoded = (object) array(
362
  'error' => (object) array(
372
  return $decoded;
373
  }
374
 
375
+
376
+ /**
377
+ * Makes an HTTP request. This method can be overridden by subclasses if
378
+ * developers want to do fancier things or use something other than curl to
379
+ * make the request.
380
+ *
381
+ * @param string $pCanonizedPath The URL to make the request to
382
+ * @param string $pMethod HTTP method
383
+ * @param array $pParams The parameters to use for the POST body
384
+ * @param null|resource $pCurlHandler Initialized curl handle
385
+ *
386
+ * @return object[]|object|null
387
+ *
388
+ * @throws Freemius_Exception
389
+ */
390
+ public function MakeRequest(
391
+ $pCanonizedPath,
392
+ $pMethod = 'GET',
393
+ $pParams = array(),
394
+ $pCurlHandler = null
395
+ ) {
396
+ $resource = explode( '?', $pCanonizedPath );
397
+
398
+ // Only sign request if not ping.json connectivity test.
399
+ $sign_request = ( '/v1/ping.json' !== strtolower( substr( $resource[0], - strlen( '/v1/ping.json' ) ) ) );
400
+
401
+ return self::MakeStaticRequest(
402
+ $pCanonizedPath,
403
+ $pMethod,
404
+ $pParams,
405
+ $pCurlHandler,
406
+ $this->_isSandbox,
407
+ $sign_request ? array( &$this, 'SignRequest' ) : null
408
+ );
409
+ }
410
+
411
+ #region Connectivity Test ------------------------------------------------------
412
+
413
+ /**
414
+ * If successful connectivity to the API endpoint using ping.json endpoint.
415
+ *
416
+ * - OR -
417
+ *
418
+ * Validate if ping result object is valid.
419
+ *
420
+ * @param mixed $pPong
421
+ *
422
+ * @return bool
423
+ */
424
+ public static function Test( $pPong = null ) {
425
+ $pong = is_null( $pPong ) ?
426
+ self::Ping() :
427
+ $pPong;
428
+
429
+ return (
430
+ is_object( $pong ) &&
431
+ isset( $pong->api ) &&
432
+ 'pong' === $pong->api
433
+ );
434
+ }
435
+
436
+ /**
437
+ * Ping API to test connectivity.
438
+ *
439
+ * @return object
440
+ */
441
+ public static function Ping() {
442
+ try {
443
+ $result = self::MakeStaticRequest( '/v' . FS_API__VERSION . '/ping.json' );
444
+ } catch ( Freemius_Exception $e ) {
445
+ // Map to error object.
446
+ $result = (object) $e->getResult();
447
+ } catch ( Exception $e ) {
448
+ // Map to error object.
449
+ $result = (object) array(
450
+ 'error' => array(
451
+ 'type' => 'Unknown',
452
+ 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
453
+ 'code' => 'unknown',
454
+ 'http' => 402
455
+ )
456
+ );
457
+ }
458
+
459
+ return $result;
460
+ }
461
+
462
+ #endregion Connectivity Test ------------------------------------------------------
463
+
464
+ #region Connectivity Exceptions ------------------------------------------------------
465
+
466
+ /**
467
+ * @param resource $pCurlHandler
468
+ *
469
+ * @throws Freemius_Exception
470
+ */
471
+ private static function ThrowCurlException( $pCurlHandler ) {
472
+ $e = new Freemius_Exception( array(
473
+ 'error' => array(
474
+ 'code' => curl_errno( $pCurlHandler ),
475
+ 'message' => curl_error( $pCurlHandler ),
476
+ 'type' => 'CurlException',
477
+ ),
478
+ ) );
479
+
480
+ curl_close( $pCurlHandler );
481
+ throw $e;
482
+ }
483
+
484
  /**
485
  * @param string $pResult
486
  *
487
  * @throws Freemius_Exception
488
  */
489
+ private static function ThrowNoCurlException( $pResult = '' ) {
490
  throw new Freemius_Exception( array(
491
  'error' => (object) array(
492
  'type' => 'cUrlMissing',
502
  *
503
  * @throws Freemius_Exception
504
  */
505
+ private static function ThrowCloudFlareDDoSException( $pResult = '' ) {
506
  throw new Freemius_Exception( array(
507
  'error' => (object) array(
508
  'type' => 'CloudFlareDDoSProtection',
518
  *
519
  * @throws Freemius_Exception
520
  */
521
+ private static function ThrowSquidAclException( $pResult = '' ) {
522
  throw new Freemius_Exception( array(
523
  'error' => (object) array(
524
  'type' => 'SquidCacheBlock',
528
  )
529
  ) );
530
  }
531
+
532
+ #endregion Connectivity Exceptions ------------------------------------------------------
533
  }
lib/freemius/includes/sdk/FreemiusBase.php CHANGED
@@ -44,25 +44,25 @@
44
  protected $_public;
45
  protected $_secret;
46
  protected $_scope;
47
- protected $_sandbox;
48
 
49
  /**
50
- * @param string $pScope 'app', 'developer', 'user' or 'install'.
51
- * @param number $pID Element's id.
52
- * @param string $pPublic Public key.
53
- * @param string $pSecret Element's secret key.
54
- * @param bool $pSandbox Whether or not to run API in sandbox mode.
55
  */
56
- public function Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox = false ) {
57
- $this->_id = $pID;
58
- $this->_public = $pPublic;
59
- $this->_secret = $pSecret;
60
- $this->_scope = $pScope;
61
- $this->_sandbox = $pSandbox;
62
  }
63
 
64
  public function IsSandbox() {
65
- return $this->_sandbox;
66
  }
67
 
68
  function CanonizePath( $pPath ) {
@@ -139,45 +139,6 @@
139
  return $result;
140
  }
141
 
142
- /**
143
- * If successful connectivity to the API endpoint using ping.json endpoint.
144
- *
145
- * - OR -
146
- *
147
- * Validate if ping result object is valid.
148
- *
149
- * @param mixed $pPong
150
- *
151
- * @return bool
152
- */
153
- public function Test( $pPong = null ) {
154
- $pong = is_null( $pPong ) ? $this->Ping() : $pPong;
155
-
156
- return ( is_object( $pong ) && isset( $pong->api ) && 'pong' === $pong->api );
157
- }
158
-
159
- /**
160
- * Ping API to test connectivity.
161
- *
162
- * @return object
163
- */
164
- public function Ping() {
165
- return $this->_Api( '/v' . FS_API__VERSION . '/ping.json' );
166
- }
167
-
168
- /**
169
- * Find clock diff between current server to API server.
170
- *
171
- * @since 1.0.2
172
- * @return int Clock diff in seconds.
173
- */
174
- public function FindClockDiff() {
175
- $time = time();
176
- $pong = $this->_Api( '/v' . FS_API__VERSION . '/ping.json' );
177
-
178
- return ( $time - strtotime( $pong->timestamp ) );
179
- }
180
-
181
  public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
182
  return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams );
183
  }
44
  protected $_public;
45
  protected $_secret;
46
  protected $_scope;
47
+ protected $_isSandbox;
48
 
49
  /**
50
+ * @param string $pScope 'app', 'developer', 'user' or 'install'.
51
+ * @param number $pID Element's id.
52
+ * @param string $pPublic Public key.
53
+ * @param string $pSecret Element's secret key.
54
+ * @param bool $pIsSandbox Whether or not to run API in sandbox mode.
55
  */
56
+ public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) {
57
+ $this->_id = $pID;
58
+ $this->_public = $pPublic;
59
+ $this->_secret = $pSecret;
60
+ $this->_scope = $pScope;
61
+ $this->_isSandbox = $pIsSandbox;
62
  }
63
 
64
  public function IsSandbox() {
65
+ return $this->_isSandbox;
66
  }
67
 
68
  function CanonizePath( $pPath ) {
139
  return $result;
140
  }
141
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
143
  return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams );
144
  }
lib/freemius/start.php CHANGED
@@ -10,13 +10,245 @@
10
  exit;
11
  }
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
- * Freemius hooks collection:
15
- * fs_after_license_loaded
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  */
17
 
 
 
18
  if ( ! class_exists( 'Freemius' ) ) {
19
 
 
 
 
 
20
  // Configuration should be loaded first.
21
  require_once dirname( __FILE__ ) . '/config.php';
22
 
@@ -26,6 +258,7 @@
26
  require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
27
  // require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
28
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
 
29
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
30
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
31
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-key-value-storage.php';
10
  exit;
11
  }
12
 
13
+ $this_sdk_version = '1.1.6.5';
14
+
15
+ #region SDK Selection Logic --------------------------------------------------------------------
16
+
17
+ /**
18
+ * Special logic added on 1.1.6 to make sure that every Freemius powered plugin
19
+ * will ALWAYS be loaded with the newest SDK from the active Freemius powered plugins.
20
+ *
21
+ * Since Freemius SDK is backward compatible, this will make sure that all Freemius powered
22
+ * plugins will run correctly.
23
+ *
24
+ * @since 1.1.6
25
+ */
26
+
27
+ global $fs_active_plugins;
28
+
29
+ $this_sdk_relative_path = plugin_basename( dirname( __FILE__ ) );
30
+
31
+ if ( ! isset( $fs_active_plugins ) ) {
32
+ // Require SDK essentials.
33
+ require_once dirname( __FILE__ ) . '/includes/fs-essential-functions.php';
34
+
35
+ // Load all Freemius powered active plugins.
36
+ $fs_active_plugins = get_option( 'fs_active_plugins', new stdClass() );
37
+
38
+ if ( ! isset( $fs_active_plugins->plugins ) ) {
39
+ $fs_active_plugins->plugins = array();
40
+ }
41
+ }
42
+
43
+ // Update current SDK info based on the SDK path.
44
+ if ( ! isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) ||
45
+ $this_sdk_version != $fs_active_plugins->plugins[ $this_sdk_relative_path ]->version
46
+ ) {
47
+ $fs_active_plugins->plugins[ $this_sdk_relative_path ] = (object) array(
48
+ 'version' => $this_sdk_version,
49
+ 'timestamp' => time(),
50
+ 'plugin_path' => plugin_basename( fs_find_caller_plugin_file() ),
51
+ );
52
+ }
53
+
54
+ $is_current_sdk_newest = isset( $fs_active_plugins->newest ) && ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path );
55
+
56
+ if ( ! isset( $fs_active_plugins->newest ) ) {
57
+ /**
58
+ * This will be executed only once, for the first time a Freemius powered plugin is activated.
59
+ */
60
+ fs_update_sdk_newest_version( $this_sdk_relative_path );
61
+
62
+ $is_current_sdk_newest = true;
63
+ } else if ( version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '<' ) ) {
64
+ /**
65
+ * Current SDK is newer than the newest stored SDK.
66
+ */
67
+ fs_update_sdk_newest_version( $this_sdk_relative_path );
68
+
69
+ if ( class_exists( 'Freemius' ) ) {
70
+ // Older SDK version was already loaded.
71
+
72
+ if ( ! $fs_active_plugins->newest->in_activation ) {
73
+ // Re-order plugins to load this plugin first.
74
+ fs_newest_sdk_plugin_first();
75
+ }
76
+
77
+ // Refresh page.
78
+ if ( fs_redirect( $_SERVER['REQUEST_URI'] ) ) {
79
+ exit();
80
+ }
81
+ }
82
+ } else {
83
+ if ( ! function_exists( 'get_plugins' ) ) {
84
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
85
+ }
86
+
87
+ $is_newest_sdk_plugin_activate = is_plugin_active( $fs_active_plugins->newest->plugin_path );
88
+
89
+ if ( $is_current_sdk_newest &&
90
+ ! $is_newest_sdk_plugin_activate &&
91
+ ! $fs_active_plugins->newest->in_activation
92
+ ) {
93
+ // If current SDK is the newest and the plugin is NOT active, it means
94
+ // that the current plugin in activation mode.
95
+ $fs_active_plugins->newest->in_activation = true;
96
+ update_option( 'fs_active_plugins', $fs_active_plugins );
97
+ }
98
+
99
+ $is_newest_sdk_path_valid = ( $is_newest_sdk_plugin_activate || $fs_active_plugins->newest->in_activation ) && file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $this_sdk_relative_path . '/start.php' ) );
100
+
101
+ if ( ! $is_newest_sdk_path_valid && ! $is_current_sdk_newest ) {
102
+ // Plugin with newest SDK is no longer active, or SDK was moved to a different location.
103
+ unset( $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ] );
104
+ }
105
+
106
+ if ( ! ( $is_newest_sdk_plugin_activate || $fs_active_plugins->newest->in_activation ) ||
107
+ ! $is_newest_sdk_path_valid ||
108
+ // Is newest SDK downgraded.
109
+ ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
110
+ version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '>' ) )
111
+ ) {
112
+ /**
113
+ * Plugin with newest SDK is no longer active.
114
+ * OR
115
+ * The newest SDK was in the current plugin. BUT, seems like the version of
116
+ * the SDK was downgraded to a lower SDK.
117
+ */
118
+ // Find the active plugin with the newest SDK version and update the newest reference.
119
+ fs_fallback_to_newest_active_sdk();
120
+ } else {
121
+ if ( $is_newest_sdk_plugin_activate &&
122
+ $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
123
+ ( $fs_active_plugins->newest->in_activation ||
124
+ ( class_exists( 'Freemius' ) && ( ! defined( 'WP_FS__SDK_VERSION' ) || version_compare( WP_FS__SDK_VERSION, $this_sdk_version, '<' ) ) )
125
+ )
126
+
127
+ ) {
128
+ if ( $fs_active_plugins->newest->in_activation ) {
129
+ // Plugin no more in activation.
130
+ $fs_active_plugins->newest->in_activation = false;
131
+ update_option( 'fs_active_plugins', $fs_active_plugins );
132
+ }
133
+
134
+ // Reorder plugins to load plugin with newest SDK first.
135
+ if ( fs_newest_sdk_plugin_first() ) {
136
+ // Refresh page after re-order to make sure activated plugin loads newest SDK.
137
+ if ( class_exists( 'Freemius' ) ) {
138
+ if ( fs_redirect( $_SERVER['REQUEST_URI'] ) ) {
139
+ exit();
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ if ( class_exists( 'Freemius' ) ) {
148
+ // SDK was already loaded.
149
+ return;
150
+ }
151
+
152
+ if ( version_compare( $this_sdk_version, $fs_active_plugins->newest->version, '<' ) ) {
153
+ $newest_sdk_starter = fs_normalize_path( WP_PLUGIN_DIR . '/' . $fs_active_plugins->newest->sdk_path . '/start.php' );
154
+
155
+ if ( file_exists( $newest_sdk_starter ) ) {
156
+ // Reorder plugins to load plugin with newest SDK first.
157
+ fs_newest_sdk_plugin_first();
158
+
159
+ // There's a newer SDK version, load it instead of the current one!
160
+ require_once $newest_sdk_starter;
161
+
162
+ return;
163
+ }
164
+ }
165
+
166
+ #endregion SDK Selection Logic --------------------------------------------------------------------
167
+
168
+ #region Hooks & Filters Collection --------------------------------------------------------------------
169
+
170
  /**
171
+ * Freemius hooks (actions & filters) tags structure:
172
+ *
173
+ * fs_{filter/action_name}_{plugin_slug}
174
+ *
175
+ * --------------------------------------------------------
176
+ *
177
+ * Usage with WordPress' add_action() / add_filter():
178
+ *
179
+ * add_action('fs_{filter/action_name}_{plugin_slug}', $callable);
180
+ *
181
+ * --------------------------------------------------------
182
+ *
183
+ * Usage with Freemius' instance add_action() / add_filter():
184
+ *
185
+ * // No need to add 'fs_' prefix nor '_{plugin_slug}' suffix.
186
+ * my_freemius()->add_action('{action_name}', $callable);
187
+ *
188
+ * --------------------------------------------------------
189
+ *
190
+ * Freemius filters collection:
191
+ *
192
+ * fs_connect_url_{plugin_slug}
193
+ * fs_trial_promotion_message_{plugin_slug}
194
+ * fs_is_long_term_user_{plugin_slug}
195
+ * fs_uninstall_reasons_{plugin_slug}
196
+ * fs_is_plugin_update_{plugin_slug}
197
+ * fs_api_domains_{plugin_slug}
198
+ * fs_email_template_sections_{plugin_slug}
199
+ * fs_support_forum_submenu_{plugin_slug}
200
+ * fs_support_forum_url_{plugin_slug}
201
+ * fs_connect_message_{plugin_slug}
202
+ * fs_connect_message_on_update_{plugin_slug}
203
+ * fs_uninstall_confirmation_message_{plugin_slug}
204
+ * fs_pending_activation_message_{plugin_slug}
205
+ * fs_is_submenu_visible_{plugin_slug}
206
+ *
207
+ * --------------------------------------------------------
208
+ *
209
+ * Freemius actions collection:
210
+ *
211
+ * fs_after_license_loaded_{plugin_slug}
212
+ * fs_after_license_change_{plugin_slug}
213
+ * fs_after_plans_sync_{plugin_slug}
214
+ *
215
+ * fs_after_account_details_{plugin_slug}
216
+ * fs_after_account_user_sync_{plugin_slug}
217
+ * fs_after_account_plan_sync_{plugin_slug}
218
+ * fs_before_account_load_{plugin_slug}
219
+ * fs_after_account_connection_{plugin_slug}
220
+ * fs_account_property_edit_{plugin_slug}
221
+ * fs_account_email_verified_{plugin_slug}
222
+ * fs_account_page_load_before_departure_{plugin_slug}
223
+ * fs_before_account_delete_{plugin_slug}
224
+ * fs_after_account_delete_{plugin_slug}
225
+ *
226
+ * fs_sdk_version_update_{plugin_slug}
227
+ * fs_plugin_version_update_{plugin_slug}
228
+ *
229
+ * fs_initiated_{plugin_slug}
230
+ * fs_after_init_plugin_registered_{plugin_slug}
231
+ * fs_after_init_plugin_anonymous_{plugin_slug}
232
+ * fs_after_init_plugin_pending_activations_{plugin_slug}
233
+ * fs_after_init_addon_registered_{plugin_slug}
234
+ * fs_after_init_addon_anonymous_{plugin_slug}
235
+ * fs_after_init_addon_pending_activations_{plugin_slug}
236
+ *
237
+ * fs_after_premium_version_activation_{plugin_slug}
238
+ * fs_after_free_version_reactivation_{plugin_slug}
239
+ *
240
+ * fs_after_uninstall_{plugin_slug}
241
+ * fs_before_admin_menu_init_{plugin_slug}
242
  */
243
 
244
+ #endregion Hooks & Filters Collection --------------------------------------------------------------------
245
+
246
  if ( ! class_exists( 'Freemius' ) ) {
247
 
248
+ if ( ! defined( 'WP_FS__SDK_VERSION' ) ) {
249
+ define( 'WP_FS__SDK_VERSION', $this_sdk_version );
250
+ }
251
+
252
  // Configuration should be loaded first.
253
  require_once dirname( __FILE__ ) . '/config.php';
254
 
258
  require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
259
  // require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
260
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
261
+ require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-cache-manager.php';
262
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-notice-manager.php';
263
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-admin-menu-manager.php';
264
  require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-key-value-storage.php';
lib/freemius/templates/account.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.3
7
  */
8
 
 
 
 
 
9
  $slug = $VARS['slug'];
10
  /**
11
  * @var Freemius $fs
@@ -29,14 +33,15 @@
29
 
30
  <div class="wrap">
31
  <h2 class="nav-tab-wrapper">
32
- <a href="<?php $fs->get_account_url() ?>" class="nav-tab nav-tab-active"><?php _efs( 'account' ) ?></a>
33
  <?php if ( $fs->_has_addons() ) : ?>
34
- <a href="<?php echo $fs->_get_admin_page_url( 'addons' ) ?>" class="nav-tab"><?php _efs( 'add-ons' ) ?></a>
 
35
  <?php endif ?>
36
  <?php if ( $fs->is_not_paying() && $fs->has_paid_plan() ) : ?>
37
- <a href="<?php echo $fs->get_upgrade_url() ?>" class="nav-tab"><?php _efs( 'upgrade' ) ?></a>
38
  <?php if ( ! $fs->is_trial_utilized() && $fs->has_trial_plan() ) : ?>
39
- <a href="<?php echo $fs->get_trial_url() ?>" class="nav-tab"><?php _efs( 'free-trial' ) ?></a>
40
  <?php endif ?>
41
  <?php endif ?>
42
  </h2>
@@ -46,7 +51,7 @@
46
  <div class="has-sidebar has-right-sidebar">
47
  <div class="has-sidebar-content">
48
  <div class="postbox">
49
- <h3><?php _efs( 'account-details' ) ?></h3>
50
 
51
  <div class="fs-header-actions">
52
  <ul>
@@ -56,11 +61,19 @@
56
  <?php wp_nonce_field( 'delete_account' ) ?>
57
  <a href="#" onclick="if (confirm('<?php
58
  if ( $is_active_subscription ) {
59
- echo esc_attr( sprintf( __fs( 'delete-account-x-confirm' ), $plan->title ) );
60
  } else {
61
- _efs( 'delete-account-confirm' );
62
  }
63
- ?>')) this.parentNode.submit(); return false;"><?php _efs( 'delete-account' ) ?></a>
 
 
 
 
 
 
 
 
64
  </form>
65
  </li>
66
  <?php if ( $is_paying ) : ?>
@@ -70,7 +83,7 @@
70
  <input type="hidden" name="fs_action" value="deactivate_license">
71
  <?php wp_nonce_field( 'deactivate_license' ) ?>
72
  <a href="#"
73
- onclick="if (confirm('<?php _efs( 'deactivate-license-confirm' ) ?>')) this.parentNode.submit(); return false;"><?php _efs( 'deactivate-license' ) ?></a>
74
  </form>
75
  </li>
76
  <?php if ( ! $license->is_lifetime() &&
@@ -82,17 +95,17 @@
82
  <input type="hidden" name="fs_action" value="downgrade_account">
83
  <?php wp_nonce_field( 'downgrade_account' ) ?>
84
  <a href="#"
85
- onclick="if (confirm('<?php printf( __fs( 'downgrade-x-confirm' ), $plan->title, human_time_diff( time(), strtotime( $license->expiration ) ) ) ?> <?php if ( ! $license->is_block_features ) {
86
- printf( __fs( 'after-downgrade-non-blocking' ), $plan->title );
87
  } else {
88
- printf( __fs( 'after-downgrade-blocking' ), $plan->title );
89
- }?> <?php _efs( 'proceed-confirmation' ) ?>')) this.parentNode.submit(); return false;"><?php _efs( 'downgrade' ) ?></a>
90
  </form>
91
  </li>
92
  <?php endif ?>
93
  <li>
94
  &nbsp;•&nbsp;
95
- <a href="<?php echo $fs->get_upgrade_url() ?>"><?php _efs( 'change-plan' ) ?></a>
96
  </li>
97
  <?php endif ?>
98
  </ul>
@@ -103,43 +116,43 @@
103
  $profile = array();
104
  $profile[] = array(
105
  'id' => 'user_name',
106
- 'title' => __fs( 'name' ),
107
  'value' => $name
108
  );
109
  // if (isset($user->email) && false !== strpos($user->email, '@'))
110
  $profile[] = array(
111
  'id' => 'email',
112
- 'title' => __fs( 'email' ),
113
  'value' => $user->email
114
  );
115
  if ( is_numeric( $user->id ) ) {
116
  $profile[] = array(
117
  'id' => 'user_id',
118
- 'title' => __fs( 'user-id' ),
119
  'value' => $user->id
120
  );
121
  }
122
 
123
  $profile[] = array(
124
  'id' => 'site_id',
125
- 'title' => __fs( 'site-id' ),
126
  'value' => is_string( $site->id ) ?
127
  $site->id :
128
- __fs( 'no-id' )
129
  );
130
 
131
  $profile[] = array(
132
  'id' => 'site_public_key',
133
- 'title' => __fs( 'public-key' ),
134
  'value' => $site->public_key
135
  );
136
 
137
  $profile[] = array(
138
  'id' => 'site_secret_key',
139
- 'title' => __fs( 'secret-key' ),
140
  'value' => ( ( is_string( $site->secret_key ) ) ?
141
  $site->secret_key :
142
- __fs( 'no-secret' )
143
  )
144
  );
145
 
@@ -148,24 +161,24 @@
148
 
149
  $profile[] = array(
150
  'id' => 'plan',
151
- 'title' => __fs( 'plan' ),
152
  'value' => ( is_string( $trial_plan->name ) ?
153
  strtoupper( $trial_plan->title ) . ' ' :
154
- '' ) . strtoupper( __fs( 'trial' ) )
155
  );
156
  } else {
157
  $profile[] = array(
158
  'id' => 'plan',
159
- 'title' => __fs( 'plan' ),
160
  'value' => is_string( $site->plan->name ) ?
161
  strtoupper( $site->plan->title ) :
162
- strtoupper( __fs( 'free' ) )
163
  );
164
  }
165
 
166
  $profile[] = array(
167
  'id' => 'version',
168
- 'title' => __fs( 'version' ),
169
  'value' => $fs->get_plugin_version()
170
  );
171
  ?>
@@ -185,16 +198,16 @@
185
  <td>
186
  <code><?php echo htmlspecialchars( $p['value'] ) ?></code>
187
  <?php if ( 'email' === $p['id'] && ! $user->is_verified() ) : ?>
188
- <label><?php _efs( 'not-verified' ) ?></label>
189
  <?php endif ?>
190
  <?php if ( 'plan' === $p['id'] ) : ?>
191
  <?php if ( $fs->is_trial() ) : ?>
192
- <label><?php printf( __fs( 'expires-in' ), human_time_diff( time(), strtotime( $site->trial_ends ) ) ) ?></label>
193
  <?php elseif ( is_object( $license ) && ! $license->is_lifetime() ) : ?>
194
  <?php if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) : ?>
195
- <label><?php printf( __fs( 'expires-in' ), human_time_diff( time(), strtotime( $license->expiration ) ) ) ?></label>
196
  <?php elseif ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) : ?>
197
- <label><?php printf( __fs( 'renews-in' ), human_time_diff( time(), strtotime( $subscription->next_payment ) ) ) ?></label>
198
  <?php endif ?>
199
  <?php endif ?>
200
  <?php endif ?>
@@ -206,7 +219,7 @@
206
  <input type="hidden" name="fs_action" value="verify_email">
207
  <?php wp_nonce_field( 'verify_email' ) ?>
208
  <input type="submit" class="button button-small"
209
- value="<?php _efs( 'verify-email' ) ?>">
210
  </form>
211
  <?php endif ?>
212
  <?php if ( 'plan' === $p['id'] ) : ?>
@@ -220,10 +233,10 @@
220
  <?php wp_nonce_field( 'activate_license' ) ?>
221
  <input type="submit" class="button button-primary"
222
  value="<?php printf(
223
- __fs( 'activate-x-plan' ),
224
  $premium_plan->title,
225
  ( $site->is_localhost() && $license->is_free_localhost ) ?
226
- '[' . __fs( 'localhost' ) . ']' :
227
  ( 1 < $license->left() ? $license->left() . ' left' : '' )
228
  ) ?> ">
229
  </form>
@@ -231,7 +244,7 @@
231
  <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>"
232
  method="POST" class="button-group">
233
  <input type="submit" class="button"
234
- value="<?php _efs( 'sync-license' ) ?>">
235
  <input type="hidden" name="fs_action"
236
  value="<?php echo $slug ?>_sync_license">
237
  <?php wp_nonce_field( $slug . '_sync_license' ) ?>
@@ -239,8 +252,8 @@
239
  class="button<?php if ( ! $is_paying ) {
240
  echo ' button-primary';
241
  } ?> button-upgrade"><?php ( ! $is_paying ) ?
242
- _efs( 'upgrade' ) :
243
- _efs( 'change-plan' )
244
  ?></a>
245
  </form>
246
  <?php endif ?>
@@ -250,10 +263,10 @@
250
  <?php if ( $is_paying || $fs->is_trial() ) : ?>
251
  <?php if ( ! $fs->is_allowed_to_install() ) : ?>
252
  <a target="_blank" class="button button-primary"
253
- href="<?php echo $fs->_get_latest_download_local_url() ?>"><?php echo sprintf( __fs( 'download-x-version' ), $site->plan->title ) . ( is_object( $update ) ? ' [' . $update->version . ']' : '' ) ?></a>
254
  <?php elseif ( is_object( $update ) ) : ?>
255
  <a class="button button-primary"
256
- href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . $fs->get_plugin_basename() ), 'upgrade-plugin_' . $fs->get_plugin_basename() ) ?>"><?php echo __fs( 'install-update-now' ) . ' [' . $update->version . ']' ?></a>
257
  <?php endif ?>
258
  <?php endif; ?>
259
  </div>
@@ -265,7 +278,7 @@
265
  ) ) )
266
  ) : ?>
267
  <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST"
268
- onsubmit="var val = prompt('<?php printf( __fs( 'what-is-your-x' ), $p['title'] ) ?>', '<?php echo $p['value'] ?>'); if (null == val || '' === val) return false; jQuery('input[name=fs_<?php echo $p['id'] ?>_<?php echo $slug ?>]').val(val); return true;">
269
  <input type="hidden" name="fs_action" value="update_<?php echo $p['id'] ?>">
270
  <input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $slug ?>"
271
  value="">
@@ -300,9 +313,9 @@
300
  <thead>
301
  <tr>
302
  <th></th>
303
- <th><?php _efs( 'version' ) ?></th>
304
- <th><?php _efs( 'plan' ) ?></th>
305
- <th><?php _efs( 'expiration' ) ?></th>
306
  <th></th>
307
  <?php if ( defined( 'WP_FS__DEV_MODE' ) && WP_FS__DEV_MODE ) : ?>
308
  <th></th>
@@ -332,7 +345,7 @@
332
  ?>
333
  <?php if ( $fs_addon->is_not_paying() ) : ?>
334
  <?php if ( $is_current_license_expired ) : ?>
335
- <td><?php _efs( 'expired' ) ?></td>
336
  <?php endif ?>
337
  <?php $premium_license = $fs_addon->_get_available_premium_license() ?>
338
  <td<?php if ( ! $is_current_license_expired ) {
@@ -343,7 +356,7 @@
343
  <?php fs_ui_action_button(
344
  $slug, 'account',
345
  'activate_license',
346
- sprintf( __fs( 'activate-x-plan' ), $fs_addon->get_plan_title(), ( $site->is_localhost() && $premium_license->is_free_localhost ) ? '[localhost]' : ( 1 < $premium_license->left() ? $premium_license->left() . ' left' : '' ) ),
347
  array( 'plugin_id' => $addon_id )
348
  ) ?>
349
  <?php else : ?>
@@ -351,16 +364,16 @@
351
  <?php fs_ui_action_button(
352
  $slug, 'account',
353
  $slug . '_sync_license',
354
- __fs( 'sync-license' ),
355
  array( 'plugin_id' => $addon_id ),
356
  false
357
  ) ?>
358
  <?php echo sprintf( '<a href="%s" class="thickbox button button-primary" aria-label="%s" data-title="%s">%s</a>',
359
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
360
  '&TB_iframe=true&width=600&height=550' ) ),
361
- esc_attr( sprintf( __fs( 'more-information-about-x' ), $addon->title ) ),
362
  esc_attr( $addon->title ),
363
- __fs( 'upgrade' )
364
  ) ?>
365
  </div>
366
  <?php endif ?>
@@ -369,12 +382,12 @@
369
  <?php if ( is_object( $current_license ) ) : ?>
370
  <td><?php
371
  if ( $current_license->is_lifetime() ) {
372
- _efs( 'no-expiration' );
373
  } else if ( $current_license->is_expired() ) {
374
- _efs( 'expired' );
375
  } else {
376
  echo sprintf(
377
- __fs( 'in-x' ),
378
  human_time_diff( time(), strtotime( $current_license->expiration ) )
379
  );
380
  }
@@ -383,7 +396,7 @@
383
  <?php fs_ui_action_button(
384
  $slug, 'account',
385
  'deactivate_license',
386
- __fs( 'deactivate-license' ),
387
  array( 'plugin_id' => $addon_id ),
388
  false
389
  ) ?>
@@ -398,15 +411,15 @@
398
  <?php $addon_file = $fs->get_addon_basename( $addon->slug ) ?>
399
  <a class="button button-primary"
400
  href="<?php echo wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ) ?>"
401
- title="<?php esc_attr( __fs( 'activate-this-addon' ) ) ?>"
402
- class="edit"><?php _efs( 'activate' ) ?></a>
403
  <?php else : ?>
404
  <?php if ( $fs->is_allowed_to_install() ) : ?>
405
  <a class="button button-primary"
406
- href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ) ?>"><?php _efs( 'install-now' ) ?></a>
407
  <?php else : ?>
408
  <a target="_blank" class="button button-primary"
409
- href="<?php echo $fs->_get_latest_download_local_url( $addon_id ) ?>"><?php _efs( 'download-latest' ) ?></a>
410
  <?php endif ?>
411
  <?php endif ?>
412
  </td>
@@ -418,7 +431,7 @@
418
  fs_ui_action_button(
419
  $slug, 'account',
420
  'delete_account',
421
- __fs( 'delete' ),
422
  array( 'plugin_id' => $addon_id ),
423
  false
424
  );
6
  * @since 1.0.3
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  $slug = $VARS['slug'];
14
  /**
15
  * @var Freemius $fs
33
 
34
  <div class="wrap">
35
  <h2 class="nav-tab-wrapper">
36
+ <a href="<?php $fs->get_account_url() ?>" class="nav-tab nav-tab-active"><?php _efs( 'account', $slug ) ?></a>
37
  <?php if ( $fs->_has_addons() ) : ?>
38
+ <a href="<?php echo $fs->_get_admin_page_url( 'addons' ) ?>"
39
+ class="nav-tab"><?php _efs( 'add-ons', $slug ) ?></a>
40
  <?php endif ?>
41
  <?php if ( $fs->is_not_paying() && $fs->has_paid_plan() ) : ?>
42
+ <a href="<?php echo $fs->get_upgrade_url() ?>" class="nav-tab"><?php _efs( 'upgrade', $slug ) ?></a>
43
  <?php if ( ! $fs->is_trial_utilized() && $fs->has_trial_plan() ) : ?>
44
+ <a href="<?php echo $fs->get_trial_url() ?>" class="nav-tab"><?php _efs( 'free-trial', $slug ) ?></a>
45
  <?php endif ?>
46
  <?php endif ?>
47
  </h2>
51
  <div class="has-sidebar has-right-sidebar">
52
  <div class="has-sidebar-content">
53
  <div class="postbox">
54
+ <h3><?php _efs( 'account-details', $slug ) ?></h3>
55
 
56
  <div class="fs-header-actions">
57
  <ul>
61
  <?php wp_nonce_field( 'delete_account' ) ?>
62
  <a href="#" onclick="if (confirm('<?php
63
  if ( $is_active_subscription ) {
64
+ echo esc_attr( sprintf( __fs( 'delete-account-x-confirm', $slug ), $plan->title ) );
65
  } else {
66
+ _efs( 'delete-account-confirm', $slug );
67
  }
68
+ ?>')) this.parentNode.submit(); return false;"><i class="dashicons dashicons-no"></i> <?php _efs( 'delete-account', $slug ) ?></a>
69
+ </form>
70
+ </li>
71
+ <li>
72
+ &nbsp;•&nbsp;
73
+ <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST">
74
+ <input type="hidden" name="fs_action" value="<?php echo $slug ?>_sync_license">
75
+ <?php wp_nonce_field( $slug . '_sync_license' ) ?>
76
+ <a href="#" onclick="this.parentNode.submit(); return false;"><i class="dashicons dashicons-image-rotate"></i> <?php _efs( 'sync', $slug ) ?></a>
77
  </form>
78
  </li>
79
  <?php if ( $is_paying ) : ?>
83
  <input type="hidden" name="fs_action" value="deactivate_license">
84
  <?php wp_nonce_field( 'deactivate_license' ) ?>
85
  <a href="#"
86
+ onclick="if (confirm('<?php _efs( 'deactivate-license-confirm', $slug ) ?>')) this.parentNode.submit(); return false;"><i class="dashicons dashicons-admin-network"></i> <?php _efs( 'deactivate-license', $slug ) ?></a>
87
  </form>
88
  </li>
89
  <?php if ( ! $license->is_lifetime() &&
95
  <input type="hidden" name="fs_action" value="downgrade_account">
96
  <?php wp_nonce_field( 'downgrade_account' ) ?>
97
  <a href="#"
98
+ onclick="if (confirm('<?php printf( __fs( 'downgrade-x-confirm', $slug ), $plan->title, human_time_diff( time(), strtotime( $license->expiration ) ) ) ?> <?php if ( ! $license->is_block_features ) {
99
+ printf( __fs( 'after-downgrade-non-blocking', $slug ), $plan->title );
100
  } else {
101
+ printf( __fs( 'after-downgrade-blocking', $slug ), $plan->title );
102
+ }?> <?php _efs( 'proceed-confirmation', $slug ) ?>')) this.parentNode.submit(); return false;"><i class="dashicons dashicons-download"></i> <?php _efs( 'downgrade', $slug ) ?></a>
103
  </form>
104
  </li>
105
  <?php endif ?>
106
  <li>
107
  &nbsp;•&nbsp;
108
+ <a href="<?php echo $fs->get_upgrade_url() ?>"><i class="dashicons dashicons-grid-view"></i> <?php _efs( 'change-plan', $slug ) ?></a>
109
  </li>
110
  <?php endif ?>
111
  </ul>
116
  $profile = array();
117
  $profile[] = array(
118
  'id' => 'user_name',
119
+ 'title' => __fs( 'name', $slug ),
120
  'value' => $name
121
  );
122
  // if (isset($user->email) && false !== strpos($user->email, '@'))
123
  $profile[] = array(
124
  'id' => 'email',
125
+ 'title' => __fs( 'email', $slug ),
126
  'value' => $user->email
127
  );
128
  if ( is_numeric( $user->id ) ) {
129
  $profile[] = array(
130
  'id' => 'user_id',
131
+ 'title' => __fs( 'user-id', $slug ),
132
  'value' => $user->id
133
  );
134
  }
135
 
136
  $profile[] = array(
137
  'id' => 'site_id',
138
+ 'title' => __fs( 'site-id', $slug ),
139
  'value' => is_string( $site->id ) ?
140
  $site->id :
141
+ __fs( 'no-id', $slug )
142
  );
143
 
144
  $profile[] = array(
145
  'id' => 'site_public_key',
146
+ 'title' => __fs( 'public-key', $slug ),
147
  'value' => $site->public_key
148
  );
149
 
150
  $profile[] = array(
151
  'id' => 'site_secret_key',
152
+ 'title' => __fs( 'secret-key', $slug ),
153
  'value' => ( ( is_string( $site->secret_key ) ) ?
154
  $site->secret_key :
155
+ __fs( 'no-secret', $slug )
156
  )
157
  );
158
 
161
 
162
  $profile[] = array(
163
  'id' => 'plan',
164
+ 'title' => __fs( 'plan', $slug ),
165
  'value' => ( is_string( $trial_plan->name ) ?
166
  strtoupper( $trial_plan->title ) . ' ' :
167
+ '' ) . strtoupper( __fs( 'trial', $slug ) )
168
  );
169
  } else {
170
  $profile[] = array(
171
  'id' => 'plan',
172
+ 'title' => __fs( 'plan', $slug ),
173
  'value' => is_string( $site->plan->name ) ?
174
  strtoupper( $site->plan->title ) :
175
+ strtoupper( __fs( 'free', $slug ) )
176
  );
177
  }
178
 
179
  $profile[] = array(
180
  'id' => 'version',
181
+ 'title' => __fs( 'version', $slug ),
182
  'value' => $fs->get_plugin_version()
183
  );
184
  ?>
198
  <td>
199
  <code><?php echo htmlspecialchars( $p['value'] ) ?></code>
200
  <?php if ( 'email' === $p['id'] && ! $user->is_verified() ) : ?>
201
+ <label><?php _efs( 'not-verified', $slug ) ?></label>
202
  <?php endif ?>
203
  <?php if ( 'plan' === $p['id'] ) : ?>
204
  <?php if ( $fs->is_trial() ) : ?>
205
+ <label><?php printf( __fs( 'expires-in', $slug ), human_time_diff( time(), strtotime( $site->trial_ends ) ) ) ?></label>
206
  <?php elseif ( is_object( $license ) && ! $license->is_lifetime() ) : ?>
207
  <?php if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) : ?>
208
+ <label><?php printf( __fs( 'expires-in', $slug ), human_time_diff( time(), strtotime( $license->expiration ) ) ) ?></label>
209
  <?php elseif ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) : ?>
210
+ <label><?php printf( __fs( 'renews-in', $slug ), human_time_diff( time(), strtotime( $subscription->next_payment ) ) ) ?></label>
211
  <?php endif ?>
212
  <?php endif ?>
213
  <?php endif ?>
219
  <input type="hidden" name="fs_action" value="verify_email">
220
  <?php wp_nonce_field( 'verify_email' ) ?>
221
  <input type="submit" class="button button-small"
222
+ value="<?php _efs( 'verify-email', $slug ) ?>">
223
  </form>
224
  <?php endif ?>
225
  <?php if ( 'plan' === $p['id'] ) : ?>
233
  <?php wp_nonce_field( 'activate_license' ) ?>
234
  <input type="submit" class="button button-primary"
235
  value="<?php printf(
236
+ __fs( 'activate-x-plan', $slug ),
237
  $premium_plan->title,
238
  ( $site->is_localhost() && $license->is_free_localhost ) ?
239
+ '[' . __fs( 'localhost', $slug ) . ']' :
240
  ( 1 < $license->left() ? $license->left() . ' left' : '' )
241
  ) ?> ">
242
  </form>
244
  <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>"
245
  method="POST" class="button-group">
246
  <input type="submit" class="button"
247
+ value="<?php _efs( 'sync-license', $slug ) ?>">
248
  <input type="hidden" name="fs_action"
249
  value="<?php echo $slug ?>_sync_license">
250
  <?php wp_nonce_field( $slug . '_sync_license' ) ?>
252
  class="button<?php if ( ! $is_paying ) {
253
  echo ' button-primary';
254
  } ?> button-upgrade"><?php ( ! $is_paying ) ?
255
+ _efs( 'upgrade', $slug ) :
256
+ _efs( 'change-plan', $slug )
257
  ?></a>
258
  </form>
259
  <?php endif ?>
263
  <?php if ( $is_paying || $fs->is_trial() ) : ?>
264
  <?php if ( ! $fs->is_allowed_to_install() ) : ?>
265
  <a target="_blank" class="button button-primary"
266
+ href="<?php echo $fs->_get_latest_download_local_url() ?>"><?php echo sprintf( __fs( 'download-x-version', $slug ), $site->plan->title ) . ( is_object( $update ) ? ' [' . $update->version . ']' : '' ) ?></a>
267
  <?php elseif ( is_object( $update ) ) : ?>
268
  <a class="button button-primary"
269
+ href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . $fs->get_plugin_basename() ), 'upgrade-plugin_' . $fs->get_plugin_basename() ) ?>"><?php echo __fs( 'install-update-now', $slug ) . ' [' . $update->version . ']' ?></a>
270
  <?php endif ?>
271
  <?php endif; ?>
272
  </div>
278
  ) ) )
279
  ) : ?>
280
  <form action="<?php echo $fs->_get_admin_page_url( 'account' ) ?>" method="POST"
281
+ onsubmit="var val = prompt('<?php printf( __fs( 'what-is-your-x', $slug ), $p['title'] ) ?>', '<?php echo $p['value'] ?>'); if (null == val || '' === val) return false; jQuery('input[name=fs_<?php echo $p['id'] ?>_<?php echo $slug ?>]').val(val); return true;">
282
  <input type="hidden" name="fs_action" value="update_<?php echo $p['id'] ?>">
283
  <input type="hidden" name="fs_<?php echo $p['id'] ?>_<?php echo $slug ?>"
284
  value="">
313
  <thead>
314
  <tr>
315
  <th></th>
316
+ <th><?php _efs( 'version', $slug ) ?></th>
317
+ <th><?php _efs( 'plan', $slug ) ?></th>
318
+ <th><?php _efs( 'expiration', $slug ) ?></th>
319
  <th></th>
320
  <?php if ( defined( 'WP_FS__DEV_MODE' ) && WP_FS__DEV_MODE ) : ?>
321
  <th></th>
345
  ?>
346
  <?php if ( $fs_addon->is_not_paying() ) : ?>
347
  <?php if ( $is_current_license_expired ) : ?>
348
+ <td><?php _efs( 'expired', $slug ) ?></td>
349
  <?php endif ?>
350
  <?php $premium_license = $fs_addon->_get_available_premium_license() ?>
351
  <td<?php if ( ! $is_current_license_expired ) {
356
  <?php fs_ui_action_button(
357
  $slug, 'account',
358
  'activate_license',
359
+ sprintf( __fs( 'activate-x-plan', $slug ), $fs_addon->get_plan_title(), ( $site->is_localhost() && $premium_license->is_free_localhost ) ? '[localhost]' : ( 1 < $premium_license->left() ? $premium_license->left() . ' left' : '' ) ),
360
  array( 'plugin_id' => $addon_id )
361
  ) ?>
362
  <?php else : ?>
364
  <?php fs_ui_action_button(
365
  $slug, 'account',
366
  $slug . '_sync_license',
367
+ __fs( 'sync-license', $slug ),
368
  array( 'plugin_id' => $addon_id ),
369
  false
370
  ) ?>
371
  <?php echo sprintf( '<a href="%s" class="thickbox button button-primary" aria-label="%s" data-title="%s">%s</a>',
372
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
373
  '&TB_iframe=true&width=600&height=550' ) ),
374
+ esc_attr( sprintf( __fs( 'more-information-about-x', $slug ), $addon->title ) ),
375
  esc_attr( $addon->title ),
376
+ __fs( 'upgrade', $slug )
377
  ) ?>
378
  </div>
379
  <?php endif ?>
382
  <?php if ( is_object( $current_license ) ) : ?>
383
  <td><?php
384
  if ( $current_license->is_lifetime() ) {
385
+ _efs( 'no-expiration', $slug );
386
  } else if ( $current_license->is_expired() ) {
387
+ _efs( 'expired', $slug );
388
  } else {
389
  echo sprintf(
390
+ __fs( 'in-x', $slug ),
391
  human_time_diff( time(), strtotime( $current_license->expiration ) )
392
  );
393
  }
396
  <?php fs_ui_action_button(
397
  $slug, 'account',
398
  'deactivate_license',
399
+ __fs( 'deactivate-license', $slug ),
400
  array( 'plugin_id' => $addon_id ),
401
  false
402
  ) ?>
411
  <?php $addon_file = $fs->get_addon_basename( $addon->slug ) ?>
412
  <a class="button button-primary"
413
  href="<?php echo wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ) ?>"
414
+ title="<?php esc_attr( __fs( 'activate-this-addon', $slug ) ) ?>"
415
+ class="edit"><?php _efs( 'activate', $slug ) ?></a>
416
  <?php else : ?>
417
  <?php if ( $fs->is_allowed_to_install() ) : ?>
418
  <a class="button button-primary"
419
+ href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ) ?>"><?php _efs( 'install-now', $slug ) ?></a>
420
  <?php else : ?>
421
  <a target="_blank" class="button button-primary"
422
+ href="<?php echo $fs->_get_latest_download_local_url( $addon_id ) ?>"><?php _efs( 'download-latest', $slug ) ?></a>
423
  <?php endif ?>
424
  <?php endif ?>
425
  </td>
431
  fs_ui_action_button(
432
  $slug, 'account',
433
  'delete_account',
434
+ __fs( 'delete', $slug ),
435
  array( 'plugin_id' => $addon_id ),
436
  false
437
  );
lib/freemius/templates/add-ons.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.3
7
  */
8
 
 
 
 
 
9
  $slug = $VARS['slug'];
10
  /**
11
  * @var Freemius
@@ -22,7 +26,7 @@
22
  $addons = $fs->get_addons();
23
  ?>
24
  <div id="fs_addons" class="wrap">
25
- <h2><?php printf( __fs( 'add-ons-for-x' ), $fs->get_plugin_name() ) ?></h2>
26
 
27
  <div id="poststuff">
28
  <ul class="fs-cards-list">
@@ -64,7 +68,7 @@
64
  echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
65
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
66
  '&TB_iframe=true&width=600&height=550' ) ),
67
- esc_attr( sprintf( __fs( 'more-information-about-x' ), $addon->title ) ),
68
  esc_attr( $addon->title )
69
  );
70
  ?>
@@ -86,7 +90,7 @@
86
  <li class="fs-title"><?php echo $addon->title ?></li>
87
  <li class="fs-offer">
88
  <span
89
- class="fs-price"><?php echo ( 0 == $price ) ? __fs( 'free' ) : '$' . number_format( $price, 2 ) ?></span>
90
  </li>
91
  <li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
92
  </ul>
6
  * @since 1.0.3
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  $slug = $VARS['slug'];
14
  /**
15
  * @var Freemius
26
  $addons = $fs->get_addons();
27
  ?>
28
  <div id="fs_addons" class="wrap">
29
+ <h2><?php printf( __fs( 'add-ons-for-x', $slug ), $fs->get_plugin_name() ) ?></h2>
30
 
31
  <div id="poststuff">
32
  <ul class="fs-cards-list">
68
  echo sprintf( '<a href="%s" class="thickbox fs-overlay" aria-label="%s" data-title="%s"></a>',
69
  esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
70
  '&TB_iframe=true&width=600&height=550' ) ),
71
+ esc_attr( sprintf( __fs( 'more-information-about-x', $slug ), $addon->title ) ),
72
  esc_attr( $addon->title )
73
  );
74
  ?>
90
  <li class="fs-title"><?php echo $addon->title ?></li>
91
  <li class="fs-offer">
92
  <span
93
+ class="fs-price"><?php echo ( 0 == $price ) ? __fs( 'free', $slug ) : '$' . number_format( $price, 2 ) ?></span>
94
  </li>
95
  <li class="fs-description"><?php echo ! empty( $addon->info->short_description ) ? $addon->info->short_description : 'SHORT DESCRIPTION' ?></li>
96
  </ul>
lib/freemius/templates/admin-notice.php CHANGED
@@ -5,6 +5,10 @@
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.0.3
7
  */
 
 
 
 
8
  ?>
9
  <div data-id="<?php echo $VARS['id'] ?>" data-slug="<?php echo $VARS['slug'] ?>" class="<?php
10
  switch ( $VARS['type'] ) {
@@ -27,8 +31,12 @@
27
  } ?><?php if ( ! empty( $VARS['plugin'] ) ) {
28
  echo ' fs-has-title';
29
  } ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?><label
30
- class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label><?php endif ?><p>
 
 
 
 
31
  <?php if ( ! empty( $VARS['title'] ) ) : ?><b><?php echo $VARS['title'] ?></b> <?php endif ?>
32
  <?php echo $VARS['message'] ?>
33
- </p><?php if ( $VARS['sticky'] ) : ?><i class="fs-close dashicons dashicons-no"
34
- title="<?php _efs( 'dismiss' ) ?>"></i><?php endif ?></div>
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.0.3
7
  */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
  ?>
13
  <div data-id="<?php echo $VARS['id'] ?>" data-slug="<?php echo $VARS['slug'] ?>" class="<?php
14
  switch ( $VARS['type'] ) {
31
  } ?><?php if ( ! empty( $VARS['plugin'] ) ) {
32
  echo ' fs-has-title';
33
  } ?>"><?php if ( ! empty( $VARS['plugin'] ) ) : ?><label
34
+ class="fs-plugin-title"><?php echo $VARS['plugin'] ?></label><?php endif ?><?php if ( $VARS['sticky'] ) : ?>
35
+ <div class="fs-close"><i class="dashicons dashicons-no"
36
+ title="<?php _efs( 'dismiss' ) ?>"></i> <span><?php _efs( 'dismiss' ) ?></span>
37
+ </div><?php endif ?>
38
+ <div class="fs-notice-body">
39
  <?php if ( ! empty( $VARS['title'] ) ) : ?><b><?php echo $VARS['title'] ?></b> <?php endif ?>
40
  <?php echo $VARS['message'] ?>
41
+ </div>
42
+ </div>
lib/freemius/templates/all-admin-notice.php CHANGED
@@ -5,6 +5,10 @@
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.0.3
7
  */
 
 
 
 
8
  ?>
9
  <div class="<?php
10
  switch ($VARS['type']) {
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.0.3
7
  */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
  ?>
13
  <div class="<?php
14
  switch ($VARS['type']) {
lib/freemius/templates/checkout.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.3
7
  */
8
 
 
 
 
 
9
  wp_enqueue_script( 'jquery' );
10
  wp_enqueue_script( 'json2' );
11
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
6
  * @since 1.0.3
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  wp_enqueue_script( 'jquery' );
14
  wp_enqueue_script( 'json2' );
15
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
lib/freemius/templates/connect.php CHANGED
@@ -6,8 +6,12 @@
6
  * @since 1.0.7
7
  */
8
 
9
- $slug = $VARS['slug'];
10
- $fs = freemius( $slug );
 
 
 
 
11
 
12
  $fs->_enqueue_connect_essentials();
13
 
@@ -44,21 +48,44 @@
44
  </div>
45
  <div class="fs-content">
46
  <p><?php
47
- echo $fs->apply_filters( 'connect_message', sprintf(
48
- __fs( 'hey-x' ) . '<br>' .
49
- __fs( 'connect-message' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  $first_name,
51
- '<b>' . $fs->get_plugin_name() . '</b>',
52
- '<b>' . $current_user->user_login . '</b>',
53
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
54
  '<a href="' . $freemius_site_url . '" target="_blank">freemius.com</a>'
55
- ) );
56
  ?></p>
57
  </div>
58
  <div class="fs-actions">
59
  <?php if ( $fs->enable_anonymous() ) : ?>
60
  <a href="<?php echo wp_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $slug . '_skip_activation' ) ), $slug . '_skip_activation' ) ?>"
61
- class="button button-secondary" tabindex="2"><?php _efs( 'skip' ) ?></a>
62
  <?php endif ?>
63
  <?php $fs_user = Freemius::_get_user_by_email( $current_user->user_email ) ?>
64
  <?php if ( is_object( $fs_user ) ) : ?>
@@ -66,7 +93,7 @@
66
  <input type="hidden" name="fs_action" value="<?php echo $slug ?>_activate_existing">
67
  <?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
68
  <button class="button button-primary" tabindex="1"
69
- type="submit"><?php _efs( 'opt-in-connect' ) ?></button>
70
  </form>
71
  <?php else : ?>
72
  <form method="post" action="<?php echo WP_FS__ADDRESS ?>/action/service/user/install/">
@@ -76,7 +103,7 @@
76
  'user_lastname' => $current_user->user_lastname,
77
  'user_nickname' => $current_user->user_nicename,
78
  'user_email' => $current_user->user_email,
79
- 'user_ip' => fs_get_ip(),
80
  'plugin_slug' => $slug,
81
  'plugin_id' => $fs->get_id(),
82
  'plugin_public_key' => $fs->get_public_key(),
@@ -117,46 +144,57 @@
117
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
118
  <?php endforeach ?>
119
  <button class="button button-primary" tabindex="1"
120
- type="submit"><?php _efs( 'opt-in-connect' ) ?></button>
121
  </form>
122
  <?php endif ?>
123
  </div>
124
  <div class="fs-permissions">
125
- <a class="fs-trigger" href="#"><?php _efs( 'what-permissions' ) ?></a>
126
  <ul>
127
  <li>
128
  <i class="dashicons dashicons-admin-users"></i>
129
 
130
  <div>
131
- <span><?php _efs( 'permissions-profile' ) ?></span>
132
 
133
- <p><?php _efs( 'permissions-profile_desc' ) ?></p>
134
  </div>
135
  </li>
136
  <li>
137
  <i class="dashicons dashicons-wordpress"></i>
138
 
139
  <div>
140
- <span><?php _efs( 'permissions-site' ) ?></span>
141
 
142
- <p><?php _efs( 'permissions-site_desc' ) ?></p>
143
  </div>
144
  </li>
 
 
 
 
 
 
 
 
 
 
 
145
  <li>
146
  <i class="dashicons dashicons-admin-plugins"></i>
147
 
148
  <div>
149
- <span><?php _efs( 'permissions-events' ) ?></span>
150
 
151
- <p><?php _efs( 'permissions-events_desc' ) ?></p>
152
  </div>
153
  </li>
154
  </ul>
155
  </div>
156
  <div class="fs-terms">
157
- <a href="https://freemius.com/privacy/" target="_blank"><?php _efs( 'privacy-policy' ) ?></a>
158
  &nbsp;&nbsp;-&nbsp;&nbsp;
159
- <a href="https://freemius.com/terms/" target="_blank"><?php _efs( 'tos' ) ?></a>
160
  </div>
161
  </div>
162
  <script type="text/javascript">
@@ -166,7 +204,8 @@
166
  $(document.body).css({'cursor': 'wait'});
167
  });
168
  $('.button.button-primary').on('click', function () {
169
- $(this).html('<?php _efs( 'activating' ) ?>...').css({'cursor': 'wait'});
 
170
  });
171
  $('.fs-permissions .fs-trigger').on('click', function () {
172
  $('.fs-permissions').toggleClass('fs-open');
6
  * @since 1.0.7
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ $slug = $VARS['slug'];
14
+ $fs = freemius( $slug );
15
 
16
  $fs->_enqueue_connect_essentials();
17
 
48
  </div>
49
  <div class="fs-content">
50
  <p><?php
51
+ $filter = 'connect_message';
52
+ $default_optin_message = 'connect-message';
53
+
54
+ if ( $fs->is_plugin_update() ) {
55
+ // If Freemius was added on a plugin update, set different
56
+ // opt-in message.
57
+ $default_optin_message = 'connect-message_on-update';
58
+
59
+ // If user customized the opt-in message on update, use
60
+ // that message. Otherwise, fallback to regular opt-in
61
+ // custom message if exist.
62
+ if ( $fs->has_filter( 'connect_message_on_update' ) ) {
63
+ $filter = 'connect_message_on_update';
64
+ }
65
+ }
66
+
67
+ echo $fs->apply_filters( $filter,
68
+ sprintf(
69
+ __fs( 'hey-x', $slug ) . '<br>' .
70
+ __fs( $default_optin_message, $slug ),
71
+ $first_name,
72
+ '<b>' . $fs->get_plugin_name() . '</b>',
73
+ '<b>' . $current_user->user_login . '</b>',
74
+ '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
75
+ '<a href="' . $freemius_site_url . '" target="_blank">freemius.com</a>'
76
+ ),
77
  $first_name,
78
+ $fs->get_plugin_name(),
79
+ $current_user->user_login,
80
  '<a href="' . $site_url . '" target="_blank">' . $site_url . '</a>',
81
  '<a href="' . $freemius_site_url . '" target="_blank">freemius.com</a>'
82
+ );
83
  ?></p>
84
  </div>
85
  <div class="fs-actions">
86
  <?php if ( $fs->enable_anonymous() ) : ?>
87
  <a href="<?php echo wp_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $slug . '_skip_activation' ) ), $slug . '_skip_activation' ) ?>"
88
+ class="button button-secondary" tabindex="2"><?php _efs( 'skip', $slug ) ?></a>
89
  <?php endif ?>
90
  <?php $fs_user = Freemius::_get_user_by_email( $current_user->user_email ) ?>
91
  <?php if ( is_object( $fs_user ) ) : ?>
93
  <input type="hidden" name="fs_action" value="<?php echo $slug ?>_activate_existing">
94
  <?php wp_nonce_field( 'activate_existing_' . $fs->get_public_key() ) ?>
95
  <button class="button button-primary" tabindex="1"
96
+ type="submit"><?php _efs( 'opt-in-connect', $slug ) ?></button>
97
  </form>
98
  <?php else : ?>
99
  <form method="post" action="<?php echo WP_FS__ADDRESS ?>/action/service/user/install/">
103
  'user_lastname' => $current_user->user_lastname,
104
  'user_nickname' => $current_user->user_nicename,
105
  'user_email' => $current_user->user_email,
106
+ 'user_ip' => WP_FS__REMOTE_ADDR,
107
  'plugin_slug' => $slug,
108
  'plugin_id' => $fs->get_id(),
109
  'plugin_public_key' => $fs->get_public_key(),
144
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
145
  <?php endforeach ?>
146
  <button class="button button-primary" tabindex="1"
147
+ type="submit"><?php _efs( 'opt-in-connect', $slug ) ?></button>
148
  </form>
149
  <?php endif ?>
150
  </div>
151
  <div class="fs-permissions">
152
+ <a class="fs-trigger" href="#"><?php _efs( 'what-permissions', $slug ) ?></a>
153
  <ul>
154
  <li>
155
  <i class="dashicons dashicons-admin-users"></i>
156
 
157
  <div>
158
+ <span><?php _efs( 'permissions-profile', $slug ) ?></span>
159
 
160
+ <p><?php _efs( 'permissions-profile_desc', $slug ) ?></p>
161
  </div>
162
  </li>
163
  <li>
164
  <i class="dashicons dashicons-wordpress"></i>
165
 
166
  <div>
167
+ <span><?php _efs( 'permissions-site', $slug ) ?></span>
168
 
169
+ <p><?php _efs( 'permissions-site_desc', $slug ) ?></p>
170
  </div>
171
  </li>
172
+ <?php if ( $fs->is_permission_requested( 'newsletter' ) ) : ?>
173
+ <li>
174
+ <i class="dashicons dashicons-email-alt"></i>
175
+
176
+ <div>
177
+ <span><?php _efs( 'permissions-newsletter', $slug ) ?></span>
178
+
179
+ <p><?php _efs( 'permissions-newsletter_desc', $slug ) ?></p>
180
+ </div>
181
+ </li>
182
+ <?php endif ?>
183
  <li>
184
  <i class="dashicons dashicons-admin-plugins"></i>
185
 
186
  <div>
187
+ <span><?php _efs( 'permissions-events', $slug ) ?></span>
188
 
189
+ <p><?php _efs( 'permissions-events_desc', $slug ) ?></p>
190
  </div>
191
  </li>
192
  </ul>
193
  </div>
194
  <div class="fs-terms">
195
+ <a href="https://freemius.com/privacy/" target="_blank"><?php _efs( 'privacy-policy', $slug ) ?></a>
196
  &nbsp;&nbsp;-&nbsp;&nbsp;
197
+ <a href="https://freemius.com/terms/" target="_blank"><?php _efs( 'tos', $slug ) ?></a>
198
  </div>
199
  </div>
200
  <script type="text/javascript">
204
  $(document.body).css({'cursor': 'wait'});
205
  });
206
  $('.button.button-primary').on('click', function () {
207
+ $(this).addClass('fs-loading');
208
+ $(this).html('<?php _efs( 'activating' , $slug ) ?>...').css({'cursor': 'wait'});
209
  });
210
  $('.fs-permissions .fs-trigger').on('click', function () {
211
  $('.fs-permissions').toggleClass('fs-open');
lib/freemius/templates/contact.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.3
7
  */
8
 
 
 
 
 
9
  wp_enqueue_script( 'jquery' );
10
  wp_enqueue_script( 'json2' );
11
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
6
  * @since 1.0.3
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  wp_enqueue_script( 'jquery' );
14
  wp_enqueue_script( 'json2' );
15
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
lib/freemius/templates/deactivation-feedback-modal.php CHANGED
@@ -5,6 +5,11 @@
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.1.2
7
  */
 
 
 
 
 
8
  $slug = $VARS['slug'];
9
  $fs = freemius( $slug );
10
 
@@ -27,11 +32,11 @@
27
  + ' <div class="fs-modal-dialog">'
28
  + ' <div class="fs-modal-body">'
29
  + ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
30
- + ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php printf( __fs( 'deactivation-share-reason' ) ); ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
31
  + ' </div>'
32
  + ' <div class="fs-modal-footer">'
33
  + ' <a href="#" class="button button-secondary button-deactivate"></a>'
34
- + ' <a href="#" class="button button-primary button-close"><?php printf( __fs( 'deactivation-modal-button-cancel' ) ); ?></a>'
35
  + ' </div>'
36
  + ' </div>'
37
  + '</div>',
@@ -100,7 +105,7 @@
100
  var _parent = $( this ).parents( 'li:first' );
101
 
102
  $modal.find( '.reason-input' ).remove();
103
- $modal.find( '.button-deactivate').text( '<?php printf( __fs( 'deactivation-modal-button-submit' ) ); ?>' );
104
 
105
  if ( _parent.hasClass( 'has-input' ) ) {
106
  var inputType = _parent.data( 'input-type' ),
@@ -183,9 +188,9 @@
183
 
184
  // Reset the deactivate button's text.
185
  if ( 'confirm' === getCurrentPanel() ) {
186
- $deactivateButton.text( '<?php printf( __fs( 'deactivation-modal-button-confirm' ) ); ?>' );
187
  } else {
188
- $deactivateButton.text( '<?php printf( __fs( 'deactivation-modal-button-deactivate' ) ); ?>' );
189
  }
190
  }
191
 
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.1.2
7
  */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  $slug = $VARS['slug'];
14
  $fs = freemius( $slug );
15
 
32
  + ' <div class="fs-modal-dialog">'
33
  + ' <div class="fs-modal-body">'
34
  + ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
35
+ + ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php printf( __fs( 'deactivation-share-reason' , $slug ) ); ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
36
  + ' </div>'
37
  + ' <div class="fs-modal-footer">'
38
  + ' <a href="#" class="button button-secondary button-deactivate"></a>'
39
+ + ' <a href="#" class="button button-primary button-close"><?php printf( __fs( 'deactivation-modal-button-cancel' , $slug ) ); ?></a>'
40
  + ' </div>'
41
  + ' </div>'
42
  + '</div>',
105
  var _parent = $( this ).parents( 'li:first' );
106
 
107
  $modal.find( '.reason-input' ).remove();
108
+ $modal.find( '.button-deactivate').text( '<?php printf( __fs( 'deactivation-modal-button-submit' , $slug ) ); ?>' );
109
 
110
  if ( _parent.hasClass( 'has-input' ) ) {
111
  var inputType = _parent.data( 'input-type' ),
188
 
189
  // Reset the deactivate button's text.
190
  if ( 'confirm' === getCurrentPanel() ) {
191
+ $deactivateButton.text( '<?php printf( __fs( 'deactivation-modal-button-confirm' , $slug ) ); ?>' );
192
  } else {
193
+ $deactivateButton.text( '<?php printf( __fs( 'deactivation-modal-button-deactivate' , $slug ) ); ?>' );
194
  }
195
  }
196
 
lib/freemius/templates/debug.php CHANGED
@@ -1,34 +1,149 @@
1
- <h2><?php _efs( 'plugin-installs' ) ?> / <?php _efs( 'sites' ) ?></h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <?php
3
  /**
4
  * @var FS_Site[] $sites
5
  */
6
  $sites = $VARS['sites'];
7
  ?>
8
- <table id="fs_installs" class="widefat">
9
- <thead>
10
- <tr>
11
- <th><?php _efs( 'id' ) ?></th>
12
- <th><?php _efs( 'plugin' ) ?></th>
13
- <th><?php _efs( 'plan' ) ?></th>
14
- <th><?php _efs( 'public-key' ) ?></th>
15
- <th><?php _efs( 'secret-key' ) ?></th>
16
- </tr>
17
- </thead>
18
- <tbody>
19
- <?php foreach ( $sites as $plugin_basename => $site ) : ?>
20
  <tr>
21
- <td><?php echo $site->id ?></td>
22
- <td><?php echo dirname( $plugin_basename ) ?></td>
23
- <td><?php
24
- echo is_object( $site->plan ) ? $site->plan->name : ''
25
- ?></td>
26
- <td><?php echo $site->public_key ?></td>
27
- <td><?php echo $site->secret_key ?></td>
28
  </tr>
29
- <?php endforeach ?>
30
- </tbody>
31
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
32
  <?php
33
  $addons = $VARS['addons'];
34
  ?>
@@ -63,41 +178,36 @@
63
  </tbody>
64
  </table>
65
  <?php endforeach ?>
66
- <h2><?php _efs( 'users' ) ?></h2>
67
  <?php
68
  /**
69
  * @var FS_User[] $users
70
  */
71
  $users = $VARS['users'];
72
  ?>
73
- <table id="fs_users" class="widefat">
74
- <thead>
75
- <tr>
76
- <th><?php _efs( 'id' ) ?></th>
77
- <th><?php _efs( 'name' ) ?></th>
78
- <th><?php _efs( 'email' ) ?></th>
79
- <th><?php _efs( 'verified' ) ?></th>
80
- <th><?php _efs( 'public-key' ) ?></th>
81
- <th><?php _efs( 'secret-key' ) ?></th>
82
- </tr>
83
- </thead>
84
- <tbody>
85
- <?php foreach ( $users as $user_id => $user ) : ?>
86
  <tr>
87
- <td><?php echo $user->id ?></td>
88
- <td><?php echo $user->get_name() ?></td>
89
- <td><?php echo $user->email ?></td>
90
- <td><?php echo json_encode( $user->is_verified ) ?></td>
91
- <td><?php echo $user->public_key ?></td>
92
- <td><?php echo $user->secret_key ?></td>
93
  </tr>
94
- <?php endforeach ?>
95
- </tbody>
96
- </table>
97
- <br><br>
98
- <form action="" method="POST">
99
- <input type="hidden" name="fs_action" value="delete_all_accounts">
100
- <?php wp_nonce_field( 'delete_all_accounts' ) ?>
101
- <button class="button button-primary"
102
- onclick="if (confirm('<?php _efs( 'delete-all-confirm' ) ?>')) this.parentNode.submit(); return false;"><?php _efs( 'delete-all-accounts' ) ?></button>
103
- </form>
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.1.1
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ global $fs_active_plugins;
14
+
15
+ $fs_options = FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true );
16
+ ?>
17
+ <h1><?php echo __fs( 'Freemius Debug' ) . ' - ' . __fs( 'SDK' ) . ' v.' . $fs_active_plugins->newest->version ?></h1>
18
+ <h2><?php _efs( 'actions' ) ?></h2>
19
+ <table>
20
+ <tbody>
21
+ <tr>
22
+ <td>
23
+ <!-- Delete All Accounts -->
24
+ <form action="" method="POST">
25
+ <input type="hidden" name="fs_action" value="delete_all_accounts">
26
+ <?php wp_nonce_field( 'delete_all_accounts' ) ?>
27
+ <button class="button button-primary"
28
+ onclick="if (confirm('<?php _efs( 'delete-all-confirm' ) ?>')) this.parentNode.submit(); return false;"><?php _efs( 'delete-all-accounts' ) ?></button>
29
+ </form>
30
+ </td>
31
+ <td>
32
+ <!-- Clear API Cache -->
33
+ <form action="" method="POST">
34
+ <input type="hidden" name="fs_clear_api_cache" value="true">
35
+ <button class="button button-primary"><?php _efs( 'clear-api-cache' ) ?></button>
36
+ </form>
37
+ </td>
38
+ <td>
39
+ <!-- Sync Data with Server -->
40
+ <form action="" method="POST">
41
+ <input type="hidden" name="background_sync" value="true">
42
+ <button class="button button-primary"><?php _efs( 'sync-data-from-server' ) ?></button>
43
+ </form>
44
+ </td>
45
+ </tr>
46
+ </tbody>
47
+ </table>
48
+ <h2><?php _efs( 'sdk-versions' ) ?></h2>
49
+ <table id="fs_sdks" class="widefat">
50
+ <thead>
51
+ <tr>
52
+ <th><?php _efs( 'version' ) ?></th>
53
+ <th><?php _efs( 'sdk-path' ) ?></th>
54
+ <th><?php _efs( 'plugin-path' ) ?></th>
55
+ <th><?php _efs( 'is-active' ) ?></th>
56
+ </tr>
57
+ </thead>
58
+ <tbody>
59
+ <?php foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) : ?>
60
+ <?php $is_active = ( WP_FS__SDK_VERSION == $data->version ) ?>
61
+ <tr<?php if ( $is_active ) {
62
+ echo ' style="background: #E6FFE6; font-weight: bold"';
63
+ } ?>>
64
+ <td><?php echo $data->version ?></td>
65
+ <td><?php echo $sdk_path ?></td>
66
+ <td><?php echo $data->plugin_path ?></td>
67
+ <td><?php echo ( $is_active ) ? 'Active' : 'Inactive' ?></td>
68
+ </tr>
69
+ <?php endforeach ?>
70
+ </tbody>
71
+ </table>
72
+ <?php $plugins = $fs_options->get_option( 'plugins' ) ?>
73
+ <?php if ( is_array( $plugins ) && 0 < count( $plugins ) ) : ?>
74
+ <h2><?php _efs( 'plugins' ) ?></h2>
75
+ <table id="fs_plugins" class="widefat">
76
+ <thead>
77
+ <tr>
78
+ <th><?php _efs( 'id' ) ?></th>
79
+ <th><?php _efs( 'slug' ) ?></th>
80
+ <th><?php _efs( 'version' ) ?></th>
81
+ <th><?php _efs( 'title' ) ?></th>
82
+ <th><?php _efs( 'api' ) ?></th>
83
+ <th><?php _efs( 'freemius-state' ) ?></th>
84
+ <th><?php _efs( 'plugin-path' ) ?></th>
85
+ <th><?php _efs( 'public-key' ) ?></th>
86
+ </tr>
87
+ </thead>
88
+ <tbody>
89
+ <?php foreach ( $plugins as $slug => $data ) : ?>
90
+ <?php $is_active = is_plugin_active( $data->file ) ?>
91
+ <?php $fs = $is_active ? freemius( $slug ) : null ?>
92
+ <tr<?php if ( $is_active ) {
93
+ echo ' style="background: #E6FFE6; font-weight: bold"';
94
+ } ?>>
95
+ <td><?php echo $data->id ?></td>
96
+ <td><?php echo $slug ?></td>
97
+ <td><?php echo $data->version ?></td>
98
+ <td><?php echo $data->title ?></td>
99
+ <td><?php if ( $is_active ) {
100
+ echo $fs->has_api_connectivity() ?
101
+ __fs( 'connected' ) :
102
+ __fs( 'blocked' );
103
+ } ?></td>
104
+ <td><?php if ( $is_active ) {
105
+ echo $fs->is_on() ?
106
+ __fs( 'on' ) :
107
+ __fs( 'off' );
108
+ } ?></td>
109
+ <td><?php echo $data->file ?></td>
110
+ <td><?php echo $data->public_key ?></td>
111
+ </tr>
112
+ <?php endforeach ?>
113
+ </tbody>
114
+ </table>
115
+ <?php endif ?>
116
  <?php
117
  /**
118
  * @var FS_Site[] $sites
119
  */
120
  $sites = $VARS['sites'];
121
  ?>
122
+ <?php if ( is_array( $sites ) && 0 < count( $sites ) ) : ?>
123
+ <h2><?php _efs( 'plugin-installs' ) ?> / <?php _efs( 'sites' ) ?></h2>
124
+ <table id="fs_installs" class="widefat">
125
+ <thead>
 
 
 
 
 
 
 
 
126
  <tr>
127
+ <th><?php _efs( 'id' ) ?></th>
128
+ <th><?php _efs( 'plan' ) ?></th>
129
+ <th><?php _efs( 'public-key' ) ?></th>
130
+ <th><?php _efs( 'secret-key' ) ?></th>
 
 
 
131
  </tr>
132
+ </thead>
133
+ <tbody>
134
+ <?php foreach ( $sites as $slug => $site ) : ?>
135
+ <tr>
136
+ <td><?php echo $site->id ?></td>
137
+ <td><?php
138
+ echo is_object( $site->plan ) ? $site->plan->name : ''
139
+ ?></td>
140
+ <td><?php echo $site->public_key ?></td>
141
+ <td><?php echo $site->secret_key ?></td>
142
+ </tr>
143
+ <?php endforeach ?>
144
+ </tbody>
145
+ </table>
146
+ <?php endif ?>
147
  <?php
148
  $addons = $VARS['addons'];
149
  ?>
178
  </tbody>
179
  </table>
180
  <?php endforeach ?>
 
181
  <?php
182
  /**
183
  * @var FS_User[] $users
184
  */
185
  $users = $VARS['users'];
186
  ?>
187
+ <?php if ( is_array( $users ) && 0 < count( $users ) ) : ?>
188
+ <h2><?php _efs( 'users' ) ?></h2>
189
+ <table id="fs_users" class="widefat">
190
+ <thead>
 
 
 
 
 
 
 
 
 
191
  <tr>
192
+ <th><?php _efs( 'id' ) ?></th>
193
+ <th><?php _efs( 'name' ) ?></th>
194
+ <th><?php _efs( 'email' ) ?></th>
195
+ <th><?php _efs( 'verified' ) ?></th>
196
+ <th><?php _efs( 'public-key' ) ?></th>
197
+ <th><?php _efs( 'secret-key' ) ?></th>
198
  </tr>
199
+ </thead>
200
+ <tbody>
201
+ <?php foreach ( $users as $user_id => $user ) : ?>
202
+ <tr>
203
+ <td><?php echo $user->id ?></td>
204
+ <td><?php echo $user->get_name() ?></td>
205
+ <td><?php echo $user->email ?></td>
206
+ <td><?php echo json_encode( $user->is_verified ) ?></td>
207
+ <td><?php echo $user->public_key ?></td>
208
+ <td><?php echo $user->secret_key ?></td>
209
+ </tr>
210
+ <?php endforeach ?>
211
+ </tbody>
212
+ </table>
213
+ <?php endif ?>
lib/freemius/templates/email.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.1.1
7
  */
8
 
 
 
 
 
9
  $sections = $VARS['sections'];
10
  ?>
11
  <table>
6
  * @since 1.1.1
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  $sections = $VARS['sections'];
14
  ?>
15
  <table>
lib/freemius/templates/firewall-issues-js.php CHANGED
@@ -9,6 +9,10 @@
9
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
  * @since 1.0.9
11
  */
 
 
 
 
12
  ?>
13
  <script type="text/javascript">
14
  jQuery(document).ready(function ($) {
9
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
  * @since 1.0.9
11
  */
12
+
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
  ?>
17
  <script type="text/javascript">
18
  jQuery(document).ready(function ($) {
lib/freemius/templates/pending-activation.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.9
7
  */
8
 
 
 
 
 
9
  wp_enqueue_script( 'jquery' );
10
  wp_enqueue_script( 'json2' );
11
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
@@ -52,8 +56,8 @@
52
  <div class="fs-content">
53
  <p><?php
54
  echo $fs->apply_filters( 'pending_activation_message', sprintf(
55
- __fs( 'thanks-x' ) . '<br>' .
56
- __fs( 'pending-activation-message' ),
57
  $first_name,
58
  '<b>' . $fs->get_plugin_name() . '</b>',
59
  '<b>' . $current_user->user_email . '</b>'
@@ -92,45 +96,56 @@
92
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
93
  <?php endforeach ?>
94
  <button class="button button-primary" tabindex="1"
95
- type="submit"><?php _efs( 'resend-activation-email' ) ?></button>
96
  </form>
97
  </div>
98
  <div class="fs-permissions">
99
- <a class="fs-trigger" href="#"><?php _efs( 'what-permissions' ) ?></a>
100
  <ul>
101
  <li>
102
  <i class="dashicons dashicons-admin-users"></i>
103
 
104
  <div>
105
- <span><?php _efs( 'permissions-profile' ) ?></span>
106
 
107
- <p><?php _efs( 'permissions-profile_desc' ) ?></p>
108
  </div>
109
  </li>
110
  <li>
111
  <i class="dashicons dashicons-wordpress"></i>
112
 
113
  <div>
114
- <span><?php _efs( 'permissions-site' ) ?></span>
115
 
116
- <p><?php _efs( 'permissions-site_desc' ) ?></p>
117
  </div>
118
  </li>
 
 
 
 
 
 
 
 
 
 
 
119
  <li>
120
  <i class="dashicons dashicons-admin-plugins"></i>
121
 
122
  <div>
123
- <span><?php _efs( 'permissions-events' ) ?></span>
124
 
125
- <p><?php _efs( 'permissions-events_desc' ) ?></p>
126
  </div>
127
  </li>
128
  </ul>
129
  </div>
130
  <div class="fs-terms">
131
- <a href="https://freemius.com/privacy/" target="_blank"><?php _efs( 'privacy-policy' ) ?></a>
132
  &nbsp;&nbsp;-&nbsp;&nbsp;
133
- <a href="https://freemius.com/terms/" target="_blank"><?php _efs( 'tos' ) ?></a>
134
  </div>
135
  </div>
136
  <script type="text/javascript">
6
  * @since 1.0.9
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  wp_enqueue_script( 'jquery' );
14
  wp_enqueue_script( 'json2' );
15
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
56
  <div class="fs-content">
57
  <p><?php
58
  echo $fs->apply_filters( 'pending_activation_message', sprintf(
59
+ __fs( 'thanks-x', $slug ) . '<br>' .
60
+ __fs( 'pending-activation-message', $slug ),
61
  $first_name,
62
  '<b>' . $fs->get_plugin_name() . '</b>',
63
  '<b>' . $current_user->user_email . '</b>'
96
  <input type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>">
97
  <?php endforeach ?>
98
  <button class="button button-primary" tabindex="1"
99
+ type="submit"><?php _efs( 'resend-activation-email', $slug ) ?></button>
100
  </form>
101
  </div>
102
  <div class="fs-permissions">
103
+ <a class="fs-trigger" href="#"><?php _efs( 'what-permissions', $slug ) ?></a>
104
  <ul>
105
  <li>
106
  <i class="dashicons dashicons-admin-users"></i>
107
 
108
  <div>
109
+ <span><?php _efs( 'permissions-profile', $slug ) ?></span>
110
 
111
+ <p><?php _efs( 'permissions-profile_desc', $slug ) ?></p>
112
  </div>
113
  </li>
114
  <li>
115
  <i class="dashicons dashicons-wordpress"></i>
116
 
117
  <div>
118
+ <span><?php _efs( 'permissions-site', $slug ) ?></span>
119
 
120
+ <p><?php _efs( 'permissions-site_desc', $slug ) ?></p>
121
  </div>
122
  </li>
123
+ <?php if ( $fs->is_permission_requested( 'newsletter' ) ) : ?>
124
+ <li>
125
+ <i class="dashicons dashicons-email-alt"></i>
126
+
127
+ <div>
128
+ <span><?php _efs( 'permissions-newsletter', $slug ) ?></span>
129
+
130
+ <p><?php _efs( 'permissions-newsletter_desc', $slug ) ?></p>
131
+ </div>
132
+ </li>
133
+ <?php endif ?>
134
  <li>
135
  <i class="dashicons dashicons-admin-plugins"></i>
136
 
137
  <div>
138
+ <span><?php _efs( 'permissions-events', $slug ) ?></span>
139
 
140
+ <p><?php _efs( 'permissions-events_desc', $slug ) ?></p>
141
  </div>
142
  </li>
143
  </ul>
144
  </div>
145
  <div class="fs-terms">
146
+ <a href="https://freemius.com/privacy/" target="_blank"><?php _efs( 'privacy-policy', $slug ) ?></a>
147
  &nbsp;&nbsp;-&nbsp;&nbsp;
148
+ <a href="https://freemius.com/terms/" target="_blank"><?php _efs( 'tos', $slug ) ?></a>
149
  </div>
150
  </div>
151
  <script type="text/javascript">
lib/freemius/templates/plugin-icon.php CHANGED
@@ -5,13 +5,31 @@
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.1.4
7
  */
 
 
 
 
 
8
  $slug = $VARS['slug'];
9
  $fs = freemius( $slug );
10
 
11
- $icons = glob( fs_normalize_path( WP_FS__DIR_IMG . '/icon.*' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
13
  $icon_found = false;
14
- $local_path = fs_normalize_path( WP_FS__DIR_IMG . '/icon.png' );
15
 
16
  if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() ) {
17
  /**
@@ -35,7 +53,7 @@
35
  foreach ( $suffixes as $s ) {
36
  $headers = get_headers( $base_url . $s );
37
  if ( strpos( $headers[0], '200' ) ) {
38
- $local_path = fs_normalize_path( WP_FS__DIR_IMG . '/icon.' . substr( $s, strpos( $s, '.' ) + 1 ) );
39
  fs_download_image( $base_url . $s, $local_path );
40
  $icon_found = true;
41
  break;
@@ -45,13 +63,13 @@
45
 
46
  if ( ! $icon_found ) {
47
  // No icons found, fallback to default icon.
48
- copy( fs_normalize_path( WP_FS__DIR_IMG . '/plugin-icon.png' ), $local_path );
49
  }
50
 
51
  $icons = array( $local_path );
52
  }
53
 
54
- $relative_url = fs_img_url( substr( $icons[0], strlen( fs_normalize_path( WP_FS__DIR_IMG ) ) ) );
55
  ?>
56
  <div class="fs-plugin-icon">
57
  <img src="<?php echo $relative_url ?>"/>
5
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
  * @since 1.1.4
7
  */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  $slug = $VARS['slug'];
14
  $fs = freemius( $slug );
15
 
16
+ global $fs_active_plugins;
17
+
18
+ $img_dir = WP_FS__DIR_IMG;
19
+
20
+ if ( 1 < count( $fs_active_plugins->plugins ) ) {
21
+ foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
22
+ if ( $data->plugin_path == $fs->get_plugin_basename() ) {
23
+ $img_dir = WP_PLUGIN_DIR . '/' . $sdk_path . '/assets/img';
24
+ break;
25
+ }
26
+ }
27
+ }
28
+
29
+ $icons = glob( fs_normalize_path( $img_dir . '/icon.*' ) );
30
  if ( ! is_array( $icons ) || 0 === count( $icons ) ) {
31
  $icon_found = false;
32
+ $local_path = fs_normalize_path( $img_dir . '/icon.png' );
33
 
34
  if ( WP_FS__IS_LOCALHOST && $fs->is_org_repo_compliant() ) {
35
  /**
53
  foreach ( $suffixes as $s ) {
54
  $headers = get_headers( $base_url . $s );
55
  if ( strpos( $headers[0], '200' ) ) {
56
+ $local_path = fs_normalize_path( $img_dir . '/icon.' . substr( $s, strpos( $s, '.' ) + 1 ) );
57
  fs_download_image( $base_url . $s, $local_path );
58
  $icon_found = true;
59
  break;
63
 
64
  if ( ! $icon_found ) {
65
  // No icons found, fallback to default icon.
66
+ copy( fs_normalize_path( $img_dir . '/plugin-icon.png' ), $local_path );
67
  }
68
 
69
  $icons = array( $local_path );
70
  }
71
 
72
+ $relative_url = fs_img_url( substr( $icons[0], strlen( fs_normalize_path( $img_dir ) ) ), $img_dir );
73
  ?>
74
  <div class="fs-plugin-icon">
75
  <img src="<?php echo $relative_url ?>"/>
lib/freemius/templates/plugin-info/description.php CHANGED
@@ -1,4 +1,15 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * @var FS_Plugin $plugin
4
  */
@@ -39,7 +50,7 @@
39
  <?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
40
  <?php $screenshots = $plugin->info->screenshots ?>
41
  <div class="fs-screenshots clearfix">
42
- <h2><?php _efs( 'screenshots' ) ?></h2>
43
  <ul>
44
  <?php $i = 0;
45
  foreach ( $screenshots as $s => $url ) : ?>
@@ -49,12 +60,13 @@
49
  $url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url; ?>
50
  <li class="<?php echo ( 0 === $i % 2 ) ? 'odd' : 'even' ?>">
51
  <style>
52
- #section-description .fs-screenshots .fs-screenshot-<?php echo $i ?>
53
  {
54
  background-image: url('<?php echo $url ?>');
55
  }
56
  </style>
57
- <a href="<?php echo $url ?>" title="<?php printf( __fs( 'view-full-size-x' ), $i ) ?>"
 
58
  class="fs-screenshot-<?php echo $i ?>"></a>
59
  </li>
60
  <?php $i ++; endforeach ?>
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.0.6
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  /**
14
  * @var FS_Plugin $plugin
15
  */
50
  <?php if ( ! empty( $plugin->info->screenshots ) ) : ?>
51
  <?php $screenshots = $plugin->info->screenshots ?>
52
  <div class="fs-screenshots clearfix">
53
+ <h2><?php _efs( 'screenshots', $plugin->slug ) ?></h2>
54
  <ul>
55
  <?php $i = 0;
56
  foreach ( $screenshots as $s => $url ) : ?>
60
  $url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url; ?>
61
  <li class="<?php echo ( 0 === $i % 2 ) ? 'odd' : 'even' ?>">
62
  <style>
63
+ #section-description .fs-screenshots <?php echo ".fs-screenshot-{$i}" ?>
64
  {
65
  background-image: url('<?php echo $url ?>');
66
  }
67
  </style>
68
+ <a href="<?php echo $url ?>"
69
+ title="<?php printf( __fs( 'view-full-size-x', $plugin->slug ), $i ) ?>"
70
  class="fs-screenshot-<?php echo $i ?>"></a>
71
  </li>
72
  <?php $i ++; endforeach ?>
lib/freemius/templates/plugin-info/features.php CHANGED
@@ -1,4 +1,20 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  $plans = $VARS['plans'];
3
 
4
  $features_plan_map = array();
@@ -20,7 +36,7 @@
20
  if ( ! isset( $features_plan_map['support'] ) ) {
21
  $support_feature = new stdClass();
22
  $support_feature->id = 'support';
23
- $support_feature->title = __fs( 'Support' );
24
  $features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() );
25
  } else {
26
  $support_feature = $features_plan_map['support'];
@@ -33,7 +49,7 @@
33
  // Add updates as a feature for all plans.
34
  $updates_feature = new stdClass();
35
  $updates_feature->id = 'updates';
36
- $updates_feature->title = __fs( 'unlimited-updates' );
37
  $features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() );
38
  foreach ( $plans as $plan ) {
39
  $features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature;
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.0.6
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * @var FS_Plugin $plugin
15
+ */
16
+ $plugin = $VARS['plugin'];
17
+
18
  $plans = $VARS['plans'];
19
 
20
  $features_plan_map = array();
36
  if ( ! isset( $features_plan_map['support'] ) ) {
37
  $support_feature = new stdClass();
38
  $support_feature->id = 'support';
39
+ $support_feature->title = __fs( 'Support', $plugin->slug );
40
  $features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() );
41
  } else {
42
  $support_feature = $features_plan_map['support'];
49
  // Add updates as a feature for all plans.
50
  $updates_feature = new stdClass();
51
  $updates_feature->id = 'updates';
52
+ $updates_feature->title = __fs( 'unlimited-updates', $plugin->slug );
53
  $features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() );
54
  foreach ( $plans as $plan ) {
55
  $features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature;
lib/freemius/templates/plugin-info/screenshots.php CHANGED
@@ -1,7 +1,20 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * @var FS_Plugin $plugin
4
  */
 
 
5
  $screenshots = $VARS['screenshots'];
6
  ?>
7
  <ol>
@@ -12,7 +25,8 @@
12
  // therefore we need to set absolute URLs.
13
  $url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url; ?>
14
  <li>
15
- <a href="<?php echo $url ?>" title="<?php printf( __fs( 'view-full-size-x' ), $i ) ?>"><img
 
16
  src="<?php echo $url ?>"></a>
17
  </li>
18
  <?php $i ++; endforeach ?>
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6
+ * @since 1.0.6
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  /**
14
  * @var FS_Plugin $plugin
15
  */
16
+ $plugin = $VARS['plugin'];
17
+
18
  $screenshots = $VARS['screenshots'];
19
  ?>
20
  <ol>
25
  // therefore we need to set absolute URLs.
26
  $url = 'http' . ( WP_FS__IS_HTTPS ? 's' : '' ) . ':' . $url; ?>
27
  <li>
28
+ <a href="<?php echo $url ?>"
29
+ title="<?php printf( __fs( 'view-full-size-x', $plugin->slug ), $i ) ?>"><img
30
  src="<?php echo $url ?>"></a>
31
  </li>
32
  <?php $i ++; endforeach ?>
lib/freemius/templates/powered-by.php CHANGED
@@ -6,8 +6,12 @@
6
  * @since 1.0.5
7
  */
8
 
 
 
 
 
9
  /**
10
- * KEEP THE POWERED BY TAB AND GET ADDITIONAL - 2% - OFF THE COMMISSION
11
  */
12
 
13
  wp_enqueue_script( 'jquery' );
6
  * @since 1.0.5
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  /**
14
+ * KEEP THE POWERED BY TAB AND GET ADDITIONAL - 1% - OFF THE COMMISSION
15
  */
16
 
17
  wp_enqueue_script( 'jquery' );
lib/freemius/templates/pricing.php CHANGED
@@ -6,6 +6,10 @@
6
  * @since 1.0.3
7
  */
8
 
 
 
 
 
9
  wp_enqueue_script( 'jquery' );
10
  wp_enqueue_script( 'json2' );
11
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
6
  * @since 1.0.3
7
  */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
  wp_enqueue_script( 'jquery' );
14
  wp_enqueue_script( 'json2' );
15
  fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
lib/freemius/templates/sticky-admin-notice-js.php CHANGED
@@ -8,6 +8,10 @@
8
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
  * @since 1.0.7
10
  */
 
 
 
 
11
  ?>
12
  <script type="text/javascript" >
13
  jQuery(document).ready(function($) {
8
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
  * @since 1.0.7
10
  */
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
  ?>
16
  <script type="text/javascript" >
17
  jQuery(document).ready(function($) {
readme.txt CHANGED
@@ -5,8 +5,8 @@ Tags: BuddyPress, media, multimedia, album, audio, songs, music, video, photo, i
5
  License: GPLv2 or later
6
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
7
  Requires at least: WordPress 3.6
8
- Tested up to: 4.4
9
- Stable tag: 3.10.1
10
 
11
  Add albums, photo, audio/video encoding, privacy, sharing, front-end uploads & more. All this works on mobile/tablets devices.
12
 
@@ -140,7 +140,11 @@ http://www.youtube.com/watch?v=dJrykKQGDcs
140
 
141
  == Changelog ==
142
 
143
- = 3.10.1 [Dec 30, 2015]
 
 
 
 
144
  * Set media description before upload feature
145
  * Update privacy of all attached media on update of activity privacy
146
  * Update BuddyPress activity query filter for activity privacy
@@ -1124,8 +1128,8 @@ http://www.youtube.com/watch?v=dJrykKQGDcs
1124
 
1125
  == Upgrade Notice ==
1126
 
1127
- = 3.10.1 =
1128
- Requires BuddyPress 1.7 or higher, if using BuddyPress. Set media description before upload feature and bug fixes.
1129
 
1130
  == Sponsors ==
1131
 
5
  License: GPLv2 or later
6
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
7
  Requires at least: WordPress 3.6
8
+ Tested up to: 4.4.1
9
+ Stable tag: 3.10.2
10
 
11
  Add albums, photo, audio/video encoding, privacy, sharing, front-end uploads & more. All this works on mobile/tablets devices.
12
 
140
 
141
  == Changelog ==
142
 
143
+ = 3.10.2 [Jan 28, 2015] =
144
+ * Fix XSS vulnerability (thanks to [Brajesh](https://profiles.wordpress.org/sbrajesh/))
145
+ * Updated Freemius SDK
146
+
147
+ = 3.10.1 [Dec 30, 2015] =
148
  * Set media description before upload feature
149
  * Update privacy of all attached media on update of activity privacy
150
  * Update BuddyPress activity query filter for activity privacy
1128
 
1129
  == Upgrade Notice ==
1130
 
1131
+ = 3.10.2 =
1132
+ Requires BuddyPress 1.7 or higher, if using BuddyPress. Fix XSS vulnerability.
1133
 
1134
  == Sponsors ==
1135