WP Security Audit Log - Version 3.1.4

Version Description

Download this release

Release Info

Developer WPWhiteSecurity
Plugin Icon 128x128 WP Security Audit Log
Version 3.1.4
Comparing to
See all releases

Code changes from version 3.1.3 to 3.1.4

classes/AuditLogListView.php CHANGED
@@ -496,7 +496,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
496
  return '';
497
  }
498
 
499
- case '%RevisionLink%' == $name:
500
  $check_value = (string) $value;
501
  if ( 'NULL' !== $check_value ) {
502
  return ' Click <a target="_blank" href="' . esc_url( $value ) . '">here</a> to see the content changes.';
@@ -534,11 +534,12 @@ class WSAL_AuditLogListView extends WP_List_Table {
534
  return '<i>unknown</i>';
535
  }
536
 
537
- case '%LinkFile%' == $name:
538
  if ( 'NULL' != $value ) {
539
- return esc_html__( 'View the 404 error log file from the /wp-content/uploads/wp-security-audit-log/404s/ directory', 'wp-security-audit-log' );
 
540
  } else {
541
- return 'Click <a href="' . esc_url( admin_url( 'admin.php?page=wsal-togglealerts#tab-system-activity' ) ) . '">here</a> to log such requests to file';
542
  }
543
 
544
  case '%LogFileLink%' === $name: // Failed login file link.
@@ -553,7 +554,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
553
  }
554
 
555
  case '%LogFileText%' === $name: // Failed login file text.
556
- return '<a href="#" class="wsal_download_failed_logins" data-download-nonce="' . esc_attr( wp_create_nonce( 'wsal-download-failed-logins' ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
557
 
558
  case strncmp( $value, 'http://', 7 ) === 0:
559
  case strncmp( $value, 'https://', 7 ) === 0:
496
  return '';
497
  }
498
 
499
+ case '%RevisionLink%' === $name:
500
  $check_value = (string) $value;
501
  if ( 'NULL' !== $check_value ) {
502
  return ' Click <a target="_blank" href="' . esc_url( $value ) . '">here</a> to see the content changes.';
534
  return '<i>unknown</i>';
535
  }
536
 
537
+ case '%LinkFile%' === $name:
538
  if ( 'NULL' != $value ) {
539
+ $site_id = $this->get_view_site_id(); // Site id for multisite.
540
+ return '<a href="javascript:;" onclick="download_404_log( this )" data-log-file="' . esc_attr( $value ) . '" data-site-id="' . esc_attr( $site_id ) . '" data-nonce-404="' . esc_attr( wp_create_nonce( 'wsal-download-404-log-' . $value ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
541
  } else {
542
+ return 'Click <a href="' . esc_url( admin_url( 'admin.php?page=wsal-togglealerts#tab-system-activity' ) ) . '">here</a> to log such requests to file.';
543
  }
544
 
545
  case '%LogFileLink%' === $name: // Failed login file link.
554
  }
555
 
556
  case '%LogFileText%' === $name: // Failed login file text.
557
+ return '<a href="javascript:;" onclick="download_failed_login_log( this )" data-download-nonce="' . esc_attr( wp_create_nonce( 'wsal-download-failed-logins' ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
558
 
559
  case strncmp( $value, 'http://', 7 ) === 0:
560
  case strncmp( $value, 'https://', 7 ) === 0:
classes/Views/AuditLog.php CHANGED
@@ -49,6 +49,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
49
  add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'AjaxSearchSite' ) );
50
  add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'AjaxSwitchDB' ) );
51
  add_action( 'wp_ajax_wsal_download_failed_login_log', array( $this, 'wsal_download_failed_login_log' ) );
 
52
  add_action( 'all_admin_notices', array( $this, 'AdminNoticesPremium' ) );
53
  // Check plugin version for to dismiss the notice only until upgrade.
54
  $this->_version = WSAL_VERSION;
@@ -406,6 +407,74 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
406
  die();
407
  }
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  /**
410
  * Method: Render header of the view.
411
  */
49
  add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'AjaxSearchSite' ) );
50
  add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'AjaxSwitchDB' ) );
51
  add_action( 'wp_ajax_wsal_download_failed_login_log', array( $this, 'wsal_download_failed_login_log' ) );
52
+ add_action( 'wp_ajax_wsal_download_404_log', array( $this, 'wsal_download_404_log' ) );
53
  add_action( 'all_admin_notices', array( $this, 'AdminNoticesPremium' ) );
54
  // Check plugin version for to dismiss the notice only until upgrade.
55
  $this->_version = WSAL_VERSION;
407
  die();
408
  }
409
 
410
+ /**
411
+ * Ajax callback to download 404 log.
412
+ */
413
+ public function wsal_download_404_log() {
414
+ // Get post array through filter.
415
+ $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_STRING );
416
+ $filename = filter_input( INPUT_POST, 'log_file', FILTER_SANITIZE_STRING );
417
+ $site_id = filter_input( INPUT_POST, 'site_id', FILTER_SANITIZE_NUMBER_INT );
418
+
419
+ // If file name is empty then return error.
420
+ if ( empty( $filename ) ) {
421
+ // Nonce verification failed.
422
+ echo wp_json_encode( array(
423
+ 'success' => false,
424
+ 'message' => esc_html__( 'Log file does not exist.', 'wp-security-audit-log' ),
425
+ ) );
426
+ die();
427
+ }
428
+
429
+ // Verify nonce.
430
+ if ( ! empty( $filename ) && ! empty( $nonce ) && wp_verify_nonce( $nonce, 'wsal-download-404-log-' . $filename ) ) {
431
+ // Set log file path.
432
+ $uploads_dir = wp_upload_dir();
433
+
434
+ if ( ! $site_id ) {
435
+ $position = strpos( $filename, '/sites/' );
436
+
437
+ if ( $position ) {
438
+ $filename = substr( $filename, $position );
439
+ } else {
440
+ $position = strpos( $filename, '/wp-security-audit-log/' );
441
+ $filename = substr( $filename, $position );
442
+ }
443
+ $log_file_path = trailingslashit( $uploads_dir['basedir'] ) . $filename;
444
+ } else {
445
+ $position = strpos( $filename, '/wp-security-audit-log/' );
446
+ $filename = substr( $filename, $position );
447
+ $log_file_path = trailingslashit( $uploads_dir['basedir'] ) . $filename;
448
+ }
449
+
450
+ // Request the file.
451
+ $response = file_get_contents( $log_file_path, true );
452
+
453
+ // Check if the response is valid.
454
+ if ( $response ) {
455
+ // Return the file body.
456
+ echo wp_json_encode( array(
457
+ 'success' => true,
458
+ 'filename' => $filename,
459
+ 'file_content' => $response,
460
+ ) );
461
+ } else {
462
+ // Request failed.
463
+ echo wp_json_encode( array(
464
+ 'success' => false,
465
+ 'message' => esc_html__( 'Request to get log file failed.', 'wp-security-audit-log' ),
466
+ ) );
467
+ }
468
+ } else {
469
+ // Nonce verification failed.
470
+ echo wp_json_encode( array(
471
+ 'success' => false,
472
+ 'message' => esc_html__( 'Nonce verification failed!', 'wp-security-audit-log' ),
473
+ ) );
474
+ }
475
+ die();
476
+ }
477
+
478
  /**
479
  * Method: Render header of the view.
480
  */
defaults.php CHANGED
@@ -352,8 +352,8 @@ function wsaldefaults_wsal_init( WpSecurityAuditLog $wsal ) {
352
  array( 6003, E_CRITICAL, __( 'WordPress Administrator Notification email changed', 'wp-security-audit-log' ), __( 'Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%.', 'wp-security-audit-log' ) ),
353
  array( 6004, E_CRITICAL, __( 'WordPress was updated', 'wp-security-audit-log' ), __( 'Updated WordPress from version %OldVersion% to %NewVersion%.', 'wp-security-audit-log' ) ),
354
  array( 6005, E_CRITICAL, __( 'User changes the WordPress Permalinks', 'wp-security-audit-log' ), __( 'Changed the WordPress permalinks from %OldPattern% to %NewPattern%.', 'wp-security-audit-log' ) ),
355
- array( 6007, E_NOTICE, __( 'User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log' ), __( 'Has requested a non existing page (404 Error Pages) %Attempts% %Msg%. %LinkFile%.', 'wp-security-audit-log' ) ),
356
- array( 6023, E_NOTICE, __( 'Website Visitor User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log' ), __( 'Website Visitor Has requested a non existing page (404 Error Pages) %Attempts% %Msg%. %LinkFile%.', 'wp-security-audit-log' ) ),
357
  array( 6024, E_CRITICAL, __( 'Option WordPress Address (URL) in WordPress settings changed', 'wp-security-audit-log' ), __( 'Changed the WordPress address (URL) from %old_url% to %new_url%.', 'wp-security-audit-log' ) ),
358
  array( 6025, E_CRITICAL, __( 'Option Site Address (URL) in WordPress settings changed', 'wp-security-audit-log' ), __( 'Changed the site address (URL) from %old_url% to %new_url%.', 'wp-security-audit-log' ) ),
359
  array( 9999, E_CRITICAL, __( 'Advertising Add-ons.', 'wp-security-audit-log' ), __( '%PromoName% %PromoMessage%', 'wp-security-audit-log' ) ),
352
  array( 6003, E_CRITICAL, __( 'WordPress Administrator Notification email changed', 'wp-security-audit-log' ), __( 'Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%.', 'wp-security-audit-log' ) ),
353
  array( 6004, E_CRITICAL, __( 'WordPress was updated', 'wp-security-audit-log' ), __( 'Updated WordPress from version %OldVersion% to %NewVersion%.', 'wp-security-audit-log' ) ),
354
  array( 6005, E_CRITICAL, __( 'User changes the WordPress Permalinks', 'wp-security-audit-log' ), __( 'Changed the WordPress permalinks from %OldPattern% to %NewPattern%.', 'wp-security-audit-log' ) ),
355
+ array( 6007, E_NOTICE, __( 'User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log' ), __( 'Has requested a non existing page (404 Error Pages) %Attempts% %Msg%. %LinkFile%', 'wp-security-audit-log' ) ),
356
+ array( 6023, E_NOTICE, __( 'Website Visitor User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log' ), __( 'Website Visitor Has requested a non existing page (404 Error Pages) %Attempts% %Msg%. %LinkFile%', 'wp-security-audit-log' ) ),
357
  array( 6024, E_CRITICAL, __( 'Option WordPress Address (URL) in WordPress settings changed', 'wp-security-audit-log' ), __( 'Changed the WordPress address (URL) from %old_url% to %new_url%.', 'wp-security-audit-log' ) ),
358
  array( 6025, E_CRITICAL, __( 'Option Site Address (URL) in WordPress settings changed', 'wp-security-audit-log' ), __( 'Changed the site address (URL) from %old_url% to %new_url%.', 'wp-security-audit-log' ) ),
359
  array( 9999, E_CRITICAL, __( 'Advertising Add-ons.', 'wp-security-audit-log' ), __( '%PromoName% %PromoMessage%', 'wp-security-audit-log' ) ),
js/auditlog.js CHANGED
@@ -239,27 +239,63 @@ function download( filename, text ) {
239
  document.body.removeChild( element );
240
  }
241
 
242
- jQuery( document ).ready( function( $ ) {
243
- // Failed logins link click.
244
- $( '.wsal_download_failed_logins' ).click( function ( event ) {
245
- event.preventDefault();
246
- nonce = $( this ).data( 'download-nonce' ); // Nonce.
247
- alert = $( this ).parent().attr( 'id' ).substring( 5 );
 
 
 
 
 
 
 
248
 
249
- jQuery.ajax( {
250
- type: 'POST',
251
- url: ajaxurl,
252
- async: true,
253
- data: {
254
- action: 'wsal_download_failed_login_log',
255
- download_nonce: nonce,
256
- alert_id: alert
257
- },
258
- success: function( data ) {
259
- data = data.replace( /,/g, '\n' );
260
- // Start file download.
261
- download( 'failed_logins.log', data );
 
 
 
262
  }
263
- } );
264
  } );
265
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  document.body.removeChild( element );
240
  }
241
 
242
+ /**
243
+ * Onclick event handler to download 404 log file.
244
+ *
245
+ * @param {object} element - Current element.
246
+ */
247
+ function download_404_log( element ) {
248
+ download_nonce = jQuery( element ).data( 'nonce-404' ); // Nonce.
249
+ log_file = jQuery( element ).data( 'log-file' ); // Log file URL.
250
+ site_id = jQuery( element ).data( 'site-id' ); // Site ID.
251
+
252
+ if ( ! download_nonce || ! log_file ) {
253
+ console.log( 'Something went wrong!' );
254
+ }
255
 
256
+ jQuery.ajax( {
257
+ type: 'POST',
258
+ url: ajaxurl,
259
+ async: true,
260
+ dataType: 'json',
261
+ data: {
262
+ action: 'wsal_download_404_log',
263
+ nonce: download_nonce,
264
+ log_file: log_file,
265
+ site_id: site_id
266
+ },
267
+ success: function( data ) {
268
+ if ( data.success ) {
269
+ download( data.filename, data.file_content );
270
+ } else {
271
+ console.log( data.message );
272
  }
273
+ }
274
  } );
275
+ }
276
+
277
+ /**
278
+ * Onclick event handler to download failed login log file.
279
+ *
280
+ * @param {object} element - Current element.
281
+ */
282
+ function download_failed_login_log( element ) {
283
+ nonce = jQuery( element ).data( 'download-nonce' ); // Nonce.
284
+ alert = jQuery( element ).parent().attr( 'id' ).substring( 5 );
285
+
286
+ jQuery.ajax( {
287
+ type: 'POST',
288
+ url: ajaxurl,
289
+ async: true,
290
+ data: {
291
+ action: 'wsal_download_failed_login_log',
292
+ download_nonce: nonce,
293
+ alert_id: alert
294
+ },
295
+ success: function( data ) {
296
+ data = data.replace( /,/g, '\n' );
297
+ // Start file download.
298
+ download( 'failed_logins.log', data );
299
+ }
300
+ } );
301
+ }
readme.txt CHANGED
@@ -6,7 +6,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
  Tested up to: 4.9.4
9
- Stable tag: 3.1.3
10
  Requires PHP: 5.3
11
 
12
  An easy to use and comprehensive monitoring & activity log solution that keeps a log of all changes & user activity on your WordPress site.
@@ -179,14 +179,12 @@ Please refer to our [Support & Documentation pages](https://www.wpsecurityauditl
179
 
180
  == Changelog ==
181
 
182
- = 3.1.3(2018-03-19) =
183
 
184
  * **Improvements**
185
- * Reintroduced the count of failed logins for non WordPress users.
186
- * Reintroduced the setting to limit the number of failed logins by non WordPress users the plugin should keep a log of.
187
- * Improved the formatting of the log file for usernames used in failed logins.
188
 
189
  * **Bug Fix**
190
- * Fixed issue where new restrictions in The plugin uploads directory broke the [custom alerts](https://www.wpsecurityauditlog.com/support-documentation/create-custom-alerts-wordpress-audit-trail/)
191
 
192
  Refer to the [WP Security Audit Log change log](https://www.wpsecurityauditlog.com/plugin-change-log/) page for the complete change log.
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
  Tested up to: 4.9.4
9
+ Stable tag: 3.1.4
10
  Requires PHP: 5.3
11
 
12
  An easy to use and comprehensive monitoring & activity log solution that keeps a log of all changes & user activity on your WordPress site.
179
 
180
  == Changelog ==
181
 
182
+ = 3.1.4(2018-03-23) =
183
 
184
  * **Improvements**
185
+ * Reintroduced the functionality to download 404 error log files from activity log.
 
 
186
 
187
  * **Bug Fix**
188
+ * Freemius addressed mutliple issues in SDK for WordPress multisite (updated SDK)
189
 
190
  Refer to the [WP Security Audit Log change log](https://www.wpsecurityauditlog.com/plugin-change-log/) page for the complete change log.
sdk/freemius/includes/class-freemius.php CHANGED
@@ -2919,14 +2919,16 @@
2919
  }
2920
  }
2921
 
 
 
2922
  $vars = array(
2923
  'plugin_sites' => $all_plugins_installs,
2924
  'theme_sites' => $all_themes_installs,
2925
  'users' => self::get_all_users(),
2926
  'addons' => self::get_all_addons(),
2927
  'account_addons' => self::get_all_account_addons(),
2928
- 'plugin_licenses' => self::get_all_licenses( WP_FS__MODULE_TYPE_PLUGIN ),
2929
- 'theme_licenses' => self::get_all_licenses( WP_FS__MODULE_TYPE_THEME )
2930
  );
2931
 
2932
  fs_enqueue_local_style( 'fs_debug', '/admin/debug.css' );
@@ -3918,12 +3920,30 @@
3918
  }
3919
  }
3920
  }
 
3921
 
3922
- // Check if Freemius is on for the current plugin.
3923
- // This MUST be executed after all the plugin variables has been loaded.
3924
- if ( ! $this->is_on() ) {
3925
- return;
3926
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3927
  }
3928
 
3929
  if ( $this->has_api_connectivity() ) {
@@ -4008,15 +4028,6 @@
4008
 
4009
  // $this->deactivate_premium_only_addon_without_license();
4010
  }
4011
- } else {
4012
- if ( $this->has_addons() &&
4013
- 'plugin-information' === fs_request_get( 'tab', false ) &&
4014
- $this->get_id() == fs_request_get( 'parent_plugin_id', false )
4015
- ) {
4016
- require_once WP_FS__DIR_INCLUDES . '/fs-plugin-info-dialog.php';
4017
-
4018
- new FS_Plugin_Info_Dialog( $this );
4019
- }
4020
  }
4021
 
4022
  add_action( 'admin_init', array( &$this, '_admin_init_action' ) );
@@ -8510,6 +8521,36 @@
8510
  return $licenses;
8511
  }
8512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8513
  /**
8514
  * @author Leo Fajardo (@leorw)
8515
  * @since 2.0.0
@@ -11121,6 +11162,10 @@
11121
  $params['trial'] = 'true';
11122
  }
11123
 
 
 
 
 
11124
  return $this->_get_admin_page_url( 'pricing', $params );
11125
  }
11126
 
@@ -14030,9 +14075,13 @@
14030
  return;
14031
  }
14032
 
14033
- // First of all, set site info - otherwise we won't
 
 
 
14034
  // be able to invoke API calls.
14035
  $this->_site = new FS_Site( $addon_install );
 
14036
 
14037
  // Sync add-on plans.
14038
  $this->_sync_plans();
@@ -14040,9 +14089,6 @@
14040
  // Get site's current plan.
14041
  //$this->_site->plan = $this->_get_plan_by_id( $this->_site->plan->id );
14042
 
14043
- // Get user information based on parent's plugin.
14044
- $user = $parent_fs->get_user();
14045
-
14046
  $this->_set_account( $user, $this->_site );
14047
 
14048
  // Sync licenses.
@@ -18715,10 +18761,6 @@
18715
  function _add_license_action_link() {
18716
  $this->_logger->entrance();
18717
 
18718
- if ( $this->is_free_plan() && $this->is_addon() ) {
18719
- return;
18720
- }
18721
-
18722
  if ( ! self::is_ajax() ) {
18723
  // Inject license activation dialog UI and client side code.
18724
  add_action( 'admin_footer', array( &$this, '_add_license_activation_dialog_box' ) );
2919
  }
2920
  }
2921
 
2922
+ $licenses_by_module_type = self::get_all_licenses_by_module_type();
2923
+
2924
  $vars = array(
2925
  'plugin_sites' => $all_plugins_installs,
2926
  'theme_sites' => $all_themes_installs,
2927
  'users' => self::get_all_users(),
2928
  'addons' => self::get_all_addons(),
2929
  'account_addons' => self::get_all_account_addons(),
2930
+ 'plugin_licenses' => $licenses_by_module_type[ WP_FS__MODULE_TYPE_PLUGIN ],
2931
+ 'theme_licenses' => $licenses_by_module_type[ WP_FS__MODULE_TYPE_THEME ]
2932
  );
2933
 
2934
  fs_enqueue_local_style( 'fs_debug', '/admin/debug.css' );
3920
  }
3921
  }
3922
  }
3923
+ }
3924
 
3925
+ /**
3926
+ * This should be executed even if Freemius is off for the core module,
3927
+ * otherwise, the add-ons dialogbox won't work properly. This is esepcially
3928
+ * relevant when the developer decided to turn FS off for existing users.
3929
+ *
3930
+ * @author Vova Feldman (@svovaf)
3931
+ */
3932
+ if ( $this->is_user_in_admin() &&
3933
+ ! $this->is_addon() &&
3934
+ $this->has_addons() &&
3935
+ 'plugin-information' === fs_request_get( 'tab', false ) &&
3936
+ $this->get_id() == fs_request_get( 'parent_plugin_id', false )
3937
+ ) {
3938
+ require_once WP_FS__DIR_INCLUDES . '/fs-plugin-info-dialog.php';
3939
+
3940
+ new FS_Plugin_Info_Dialog( $this );
3941
+ }
3942
+
3943
+ // Check if Freemius is on for the current plugin.
3944
+ // This MUST be executed after all the plugin variables has been loaded.
3945
+ if ( ! $this->is_registered() && ! $this->is_on() ) {
3946
+ return;
3947
  }
3948
 
3949
  if ( $this->has_api_connectivity() ) {
4028
 
4029
  // $this->deactivate_premium_only_addon_without_license();
4030
  }
 
 
 
 
 
 
 
 
 
4031
  }
4032
 
4033
  add_action( 'admin_init', array( &$this, '_admin_init_action' ) );
8521
  return $licenses;
8522
  }
8523
 
8524
+ /**
8525
+ * @author Leo Fajardo (@leorw)
8526
+ * @since 2.0.0
8527
+ *
8528
+ * @return array
8529
+ */
8530
+ private static function get_all_licenses_by_module_type() {
8531
+ $licenses = self::get_account_option( 'all_licenses' );
8532
+
8533
+ $licenses_by_module_type = array(
8534
+ WP_FS__MODULE_TYPE_PLUGIN => array(),
8535
+ WP_FS__MODULE_TYPE_THEME => array()
8536
+ );
8537
+
8538
+ if ( ! is_array( $licenses ) ) {
8539
+ return $licenses_by_module_type;
8540
+ }
8541
+
8542
+ foreach ( $licenses as $module_id => $module_licenses ) {
8543
+ $fs = self::get_instance_by_id( $module_id );
8544
+ if ( false === $fs ) {
8545
+ continue;
8546
+ }
8547
+
8548
+ $licenses_by_module_type[ $fs->_module_type ] = array_merge( $licenses_by_module_type[ $fs->_module_type ], $module_licenses );
8549
+ }
8550
+
8551
+ return $licenses_by_module_type;
8552
+ }
8553
+
8554
  /**
8555
  * @author Leo Fajardo (@leorw)
8556
  * @since 2.0.0
11162
  $params['trial'] = 'true';
11163
  }
11164
 
11165
+ if ( $this->is_addon() ) {
11166
+ return $this->_parent->addon_url( $this->_slug );
11167
+ }
11168
+
11169
  return $this->_get_admin_page_url( 'pricing', $params );
11170
  }
11171
 
14075
  return;
14076
  }
14077
 
14078
+ // Get user information based on parent's plugin.
14079
+ $user = $parent_fs->get_user();
14080
+
14081
+ // First of all, set site and user info - otherwise we won't
14082
  // be able to invoke API calls.
14083
  $this->_site = new FS_Site( $addon_install );
14084
+ $this->_user = $user;
14085
 
14086
  // Sync add-on plans.
14087
  $this->_sync_plans();
14089
  // Get site's current plan.
14090
  //$this->_site->plan = $this->_get_plan_by_id( $this->_site->plan->id );
14091
 
 
 
 
14092
  $this->_set_account( $user, $this->_site );
14093
 
14094
  // Sync licenses.
18761
  function _add_license_action_link() {
18762
  $this->_logger->entrance();
18763
 
 
 
 
 
18764
  if ( ! self::is_ajax() ) {
18765
  // Inject license activation dialog UI and client side code.
18766
  add_action( 'admin_footer', array( &$this, '_add_license_activation_dialog_box' ) );
sdk/freemius/includes/class-fs-storage.php CHANGED
@@ -21,10 +21,9 @@
21
  */
22
  class FS_Storage {
23
  /**
24
- * @var FS_Storage
25
  */
26
- private static $_instance;
27
-
28
  /**
29
  * @var FS_Key_Value_Storage Site level storage.
30
  */
@@ -82,11 +81,13 @@
82
  * @return FS_Storage
83
  */
84
  static function instance( $module_type, $slug ) {
85
- if ( ! isset( self::$_instance ) ) {
86
- self::$_instance = new FS_Storage( $module_type, $slug );
 
 
87
  }
88
 
89
- return self::$_instance;
90
  }
91
 
92
  /**
21
  */
22
  class FS_Storage {
23
  /**
24
+ * @var FS_Storage[]
25
  */
26
+ private static $_instances = array();
 
27
  /**
28
  * @var FS_Key_Value_Storage Site level storage.
29
  */
81
  * @return FS_Storage
82
  */
83
  static function instance( $module_type, $slug ) {
84
+ $key = $module_type . ':' . $slug;
85
+
86
+ if ( ! isset( self::$_instances[ $key ] ) ) {
87
+ self::$_instances[ $key ] = new FS_Storage( $module_type, $slug );
88
  }
89
 
90
+ return self::$_instances[ $key ];
91
  }
92
 
93
  /**
sdk/freemius/includes/entities/class-fs-plugin.php CHANGED
@@ -1,117 +1,120 @@
1
  <?php
2
- /**
3
- * @package Freemius
4
- * @copyright Copyright (c) 2015, Freemius, Inc.
5
- * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
- * @since 1.0.3
7
- */
8
 
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- exit;
11
- }
12
 
13
- class FS_Plugin extends FS_Scope_Entity {
14
- /**
15
- * @since 1.0.6
16
- * @var null|number
17
- */
18
- public $parent_plugin_id;
19
- /**
20
- * @var string
21
- */
22
- public $title;
23
- /**
24
- * @var string
25
- */
26
- public $slug;
27
- /**
28
- * @since 1.2.2
29
- *
30
- * @var string 'plugin' or 'theme'
31
- */
32
- public $type;
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- #region Install Specific Properties
35
 
36
- /**
37
- * @var string
38
- */
39
- public $file;
40
- /**
41
- * @var string
42
- */
43
- public $version;
44
- /**
45
- * @var bool
46
- */
47
- public $auto_update;
48
- /**
49
- * @var FS_Plugin_Info
50
- */
51
- public $info;
52
- /**
53
- * @since 1.0.9
54
- *
55
- * @var bool
56
- */
57
- public $is_premium;
58
- /**
59
- * @since 1.0.9
60
- *
61
- * @var bool
62
- */
63
- public $is_live;
64
- /**
65
- * @author Leo Fajardo (@leorw)
66
  *
67
- * @since 1.2.3
68
- *
69
- * @var string|false false if the module doesn't have an affiliate program or one of the following:
70
- * 'selected', 'customers', or 'all'.
71
- */
72
- public $affiliate_moderation;
 
 
 
73
 
74
  const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
75
 
76
- #endregion Install Specific Properties
77
 
78
- /**
79
- * @param stdClass|bool $plugin
80
- */
81
- function __construct( $plugin = false ) {
82
- parent::__construct( $plugin );
83
 
84
- $this->is_premium = false;
85
- $this->is_live = true;
86
 
87
- if ( isset( $plugin->info ) && is_object( $plugin->info ) ) {
88
- $this->info = new FS_Plugin_Info( $plugin->info );
89
- }
90
- }
91
 
92
- /**
93
- * Check if plugin is an add-on (has parent).
94
- *
95
- * @author Vova Feldman (@svovaf)
96
- * @since 1.0.6
97
- *
98
- * @return bool
99
- */
100
- function is_addon() {
101
- return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
102
- }
103
 
104
  /**
105
  * @author Leo Fajardo (@leorw)
106
- * @since 1.2.3
107
  *
108
  * @return bool
109
  */
110
- function has_affiliate_program() {
111
  return ( ! empty( $this->affiliate_moderation ) );
112
  }
113
 
114
- static function get_type() {
115
- return 'plugin';
116
- }
117
- }
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.3
7
+ */
8
 
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
 
13
+ class FS_Plugin extends FS_Scope_Entity {
14
+ /**
15
+ * @since 1.0.6
16
+ * @var null|number
17
+ */
18
+ public $parent_plugin_id;
19
+ /**
20
+ * @var string
21
+ */
22
+ public $title;
23
+ /**
24
+ * @var string
25
+ */
26
+ public $slug;
27
+ /**
28
+ * @since 1.2.2
29
+ *
30
+ * @var string 'plugin' or 'theme'
31
+ */
32
+ public $type;
33
+ /**
34
+ * @author Leo Fajardo (@leorw)
35
+ *
36
+ * @since 1.2.3
37
+ *
38
+ * @var string|false false if the module doesn't have an affiliate program or one of the following: 'selected', 'customers', or 'all'.
39
+ */
40
+ public $affiliate_moderation;
41
+ /**
42
+ * @var bool Set to true if the free version of the module is hosted on WordPress.org. Defaults to true.
43
+ */
44
+ public $is_wp_org_compliant = true;
45
 
46
+ #region Install Specific Properties
47
 
48
+ /**
49
+ * @var string
50
+ */
51
+ public $file;
52
+ /**
53
+ * @var string
54
+ */
55
+ public $version;
56
+ /**
57
+ * @var bool
58
+ */
59
+ public $auto_update;
60
+ /**
61
+ * @var FS_Plugin_Info
62
+ */
63
+ public $info;
64
+ /**
65
+ * @since 1.0.9
 
 
 
 
 
 
 
 
 
 
 
 
66
  *
67
+ * @var bool
68
+ */
69
+ public $is_premium;
70
+ /**
71
+ * @since 1.0.9
72
+ *
73
+ * @var bool
74
+ */
75
+ public $is_live;
76
 
77
  const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
78
 
79
+ #endregion Install Specific Properties
80
 
81
+ /**
82
+ * @param stdClass|bool $plugin
83
+ */
84
+ function __construct( $plugin = false ) {
85
+ parent::__construct( $plugin );
86
 
87
+ $this->is_premium = false;
88
+ $this->is_live = true;
89
 
90
+ if ( isset( $plugin->info ) && is_object( $plugin->info ) ) {
91
+ $this->info = new FS_Plugin_Info( $plugin->info );
92
+ }
93
+ }
94
 
95
+ /**
96
+ * Check if plugin is an add-on (has parent).
97
+ *
98
+ * @author Vova Feldman (@svovaf)
99
+ * @since 1.0.6
100
+ *
101
+ * @return bool
102
+ */
103
+ function is_addon() {
104
+ return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
105
+ }
106
 
107
  /**
108
  * @author Leo Fajardo (@leorw)
109
+ * @since 1.2.3
110
  *
111
  * @return bool
112
  */
113
+ function has_affiliate_program() {
114
  return ( ! empty( $this->affiliate_moderation ) );
115
  }
116
 
117
+ static function get_type() {
118
+ return 'plugin';
119
+ }
120
+ }
sdk/freemius/includes/fs-core-functions.php CHANGED
@@ -275,6 +275,7 @@
275
  * @param string $page
276
  * @param string $action
277
  * @param string $title
 
278
  * @param array $params
279
  * @param bool $is_primary
280
  * @param bool $is_small
@@ -289,6 +290,7 @@
289
  $page,
290
  $action,
291
  $title,
 
292
  $params = array(),
293
  $is_primary = true,
294
  $is_small = false,
@@ -301,6 +303,7 @@
301
  $page,
302
  $action,
303
  $title,
 
304
  $params,
305
  $is_primary,
306
  $is_small,
@@ -318,6 +321,7 @@
318
  * @param string $page
319
  * @param string $action
320
  * @param string $title
 
321
  * @param array $params
322
  * @param bool $is_primary
323
  * @param bool $is_small
@@ -332,6 +336,7 @@
332
  $page,
333
  $action,
334
  $title,
 
335
  $params = array(),
336
  $is_primary = true,
337
  $is_small = false,
@@ -348,7 +353,7 @@
348
  $method,
349
  $action,
350
  wp_nonce_field( $action, '_wpnonce', true, false ),
351
- 'button' . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
352
  $confirmation,
353
  $title
354
  );
@@ -358,13 +363,13 @@
358
  $method,
359
  $action,
360
  wp_nonce_field( $action, '_wpnonce', true, false ),
361
- 'button' . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
362
  $title
363
  );
364
  } else {
365
  return sprintf( '<a href="%s" class="%s">%s</a></form>',
366
  wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
367
- 'button' . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
368
  $title
369
  );
370
  }
275
  * @param string $page
276
  * @param string $action
277
  * @param string $title
278
+ * @param string $button_class
279
  * @param array $params
280
  * @param bool $is_primary
281
  * @param bool $is_small
290
  $page,
291
  $action,
292
  $title,
293
+ $button_class = '',
294
  $params = array(),
295
  $is_primary = true,
296
  $is_small = false,
303
  $page,
304
  $action,
305
  $title,
306
+ $button_class,
307
  $params,
308
  $is_primary,
309
  $is_small,
321
  * @param string $page
322
  * @param string $action
323
  * @param string $title
324
+ * @param string $button_class
325
  * @param array $params
326
  * @param bool $is_primary
327
  * @param bool $is_small
336
  $page,
337
  $action,
338
  $title,
339
+ $button_class = '',
340
  $params = array(),
341
  $is_primary = true,
342
  $is_small = false,
353
  $method,
354
  $action,
355
  wp_nonce_field( $action, '_wpnonce', true, false ),
356
+ 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
357
  $confirmation,
358
  $title
359
  );
363
  $method,
364
  $action,
365
  wp_nonce_field( $action, '_wpnonce', true, false ),
366
+ 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
367
  $title
368
  );
369
  } else {
370
  return sprintf( '<a href="%s" class="%s">%s</a></form>',
371
  wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
372
+ 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
373
  $title
374
  );
375
  }
sdk/freemius/includes/fs-plugin-info-dialog.php CHANGED
@@ -1,992 +1,1110 @@
1
  <?php
2
- /**
3
- * @package Freemius
4
- * @copyright Copyright (c) 2015, Freemius, Inc.
5
- * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
- * @since 1.0.6
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- exit;
11
- }
12
-
13
- /**
14
- * Class FS_Plugin_Info_Dialog
15
- *
16
- * @author Vova Feldman (@svovaf)
17
- * @since 1.1.7
18
- */
19
- class FS_Plugin_Info_Dialog {
20
- /**
21
- * @since 1.1.7
22
- *
23
- * @var FS_Logger
24
- */
25
- private $_logger;
26
-
27
- /**
28
- * @since 1.1.7
29
- *
30
- * @var Freemius
31
- */
32
- private $_fs;
33
-
34
- function __construct( Freemius $fs ) {
35
- $this->_fs = $fs;
36
-
37
- $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $fs->get_slug() . '_info', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
38
-
39
- // Remove default plugin information action.
40
- remove_all_actions( 'install_plugins_pre_plugin-information' );
41
-
42
- // Override action with custom plugins function for add-ons.
43
- add_action( 'install_plugins_pre_plugin-information', array( &$this, 'install_plugin_information' ) );
44
-
45
- // Override request for plugin information for Add-ons.
46
- add_filter(
47
- 'fs_plugins_api',
48
- array( &$this, '_get_addon_info_filter' ),
49
- WP_FS__DEFAULT_PRIORITY, 3 );
50
- }
51
-
52
- /**
53
- * Generate add-on plugin information.
54
- *
55
- * @author Vova Feldman (@svovaf)
56
- * @since 1.0.6
57
- *
58
- * @param array $data
59
- * @param string $action
60
- * @param object|null $args
61
- *
62
- * @return array|null
63
- */
64
- function _get_addon_info_filter( $data, $action = '', $args = null ) {
65
- $this->_logger->entrance();
66
-
67
- $parent_plugin_id = fs_request_get( 'parent_plugin_id', false );
68
-
69
- if ( $this->_fs->get_id() != $parent_plugin_id ||
70
- ( 'plugin_information' !== $action ) ||
71
- ! isset( $args->slug )
72
- ) {
73
- return $data;
74
- }
75
-
76
- // Find add-on by slug.
77
- $selected_addon = $this->_fs->get_addon_by_slug($args->slug, WP_FS__DEV_MODE);
78
-
79
- if ( false === $selected_addon ) {
80
- return $data;
81
- }
82
-
83
- if ( ! isset( $selected_addon->info ) ) {
84
- // Setup some default info.
85
- $selected_addon->info = new stdClass();
86
- $selected_addon->info->selling_point_0 = 'Selling Point 1';
87
- $selected_addon->info->selling_point_1 = 'Selling Point 2';
88
- $selected_addon->info->selling_point_2 = 'Selling Point 3';
89
- $selected_addon->info->description = '<p>Tell your users all about your add-on</p>';
90
- }
91
-
92
- fs_enqueue_local_style( 'fs_addons', '/admin/add-ons.css' );
93
-
94
- $data = $args;
95
-
96
- $is_free = true;
97
-
98
- // Load add-on pricing.
99
- $has_pricing = false;
100
- $has_features = false;
101
- $plans = false;
102
-
103
- $result = $this->_fs->get_api_plugin_scope()->get( "/addons/{$selected_addon->id}/pricing.json?type=visible" );
104
-
105
- if ( ! isset( $result->error ) ) {
106
- $plans = $result->plans;
107
-
108
- if ( is_array( $plans ) ) {
109
- for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
110
- $pricing = isset( $plans[ $i ]->pricing ) ? $plans[ $i ]->pricing : null;
111
- $features = isset( $plans[ $i ]->features ) ? $plans[ $i ]->features : null;
112
-
113
- $plans[ $i ] = new FS_Plugin_Plan( $plans[ $i ] );
114
- $plan = $plans[ $i ];
115
-
116
- if ( is_array( $pricing ) && 0 < count( $pricing ) ) {
117
- $is_free = false;
118
-
119
- foreach ( $pricing as &$prices ) {
120
- $prices = new FS_Pricing( $prices );
121
- }
122
-
123
- $plan->pricing = $pricing;
124
-
125
- $has_pricing = true;
126
- }
127
-
128
- if ( is_array( $features ) && 0 < count( $features ) ) {
129
- $plan->features = $features;
130
-
131
- $has_features = true;
132
- }
133
- }
134
- }
135
- }
136
-
137
- // Fetch latest version from Freemius.
138
- $latest = $this->_fs->_fetch_latest_version( $selected_addon->id );
139
-
140
- if ( ! $is_free ) {
141
- // If paid add-on, then it's not on wordpress.org
142
- $is_wordpress_org = false;
143
- } else {
144
- // If no versions found, then assume it's a .org plugin.
145
- $is_wordpress_org = ( false === $latest );
146
- }
147
-
148
- if ( $is_wordpress_org ) {
149
- $repo_data = FS_Plugin_Updater::_fetch_plugin_info_from_repository(
150
- 'plugin_information', (object) array(
151
- 'slug' => $selected_addon->slug,
152
- 'is_ssl' => is_ssl(),
153
- 'fields' => array(
154
- 'banners' => true,
155
- 'reviews' => true,
156
- 'downloaded' => false,
157
- 'active_installs' => true
158
- )
159
- ) );
160
-
161
- if ( ! empty( $repo_data ) ) {
162
- $data = $repo_data;
163
- $data->wp_org_missing = false;
164
- } else {
165
- // Couldn't find plugin on .org.
166
- $is_wordpress_org = false;
167
-
168
- // Plugin is missing, not on Freemius nor WP.org.
169
- $data->wp_org_missing = true;
170
- }
171
- }
172
-
173
- if ( ! $is_wordpress_org ) {
174
- $data->checkout_link = $this->_fs->checkout_url();
175
- $data->fs_missing = ( false === $latest );
176
-
177
- if ( $is_free ) {
178
- $data->download_link = $this->_fs->_get_latest_download_local_url( $selected_addon->id );
179
- }
180
- }
181
-
182
- if ( ! $is_wordpress_org ) {
183
- // Fetch as much as possible info from local files.
184
- $plugin_local_data = $this->_fs->get_plugin_data();
185
- $data->name = $selected_addon->title;
186
- $data->author = $plugin_local_data['Author'];
187
- $view_vars = array( 'plugin' => $selected_addon );
188
- $data->sections = array(
189
- 'description' => fs_get_template( '/plugin-info/description.php', $view_vars ),
190
- );
191
-
192
- if ( ! empty( $selected_addon->info->banner_url ) ) {
193
- $data->banners = array(
194
- 'low' => $selected_addon->info->banner_url,
195
- );
196
- }
197
-
198
- if ( ! empty( $selected_addon->info->screenshots ) ) {
199
- $view_vars = array(
200
- 'screenshots' => $selected_addon->info->screenshots,
201
- 'plugin' => $selected_addon,
202
- );
203
- $data->sections['screenshots'] = fs_get_template( '/plugin-info/screenshots.php', $view_vars );
204
- }
205
-
206
- if ( is_object( $latest ) ) {
207
- $data->version = $latest->version;
208
- $data->last_updated = ! is_null( $latest->updated ) ? $latest->updated : $latest->created;
209
- $data->requires = $latest->requires_platform_version;
210
- $data->tested = $latest->tested_up_to_version;
211
- } else {
212
- // Add dummy version.
213
- $data->version = '1.0.0';
214
-
215
- // Add message to developer to deploy the plugin through Freemius.
216
- }
217
- }
218
-
219
- if ( $has_pricing ) {
220
- // Add plans to data.
221
- $data->plans = $plans;
222
-
223
- if ( $has_features ) {
224
- $view_vars = array(
225
- 'plans' => $plans,
226
- 'plugin' => $selected_addon,
227
- );
228
- $data->sections['features'] = fs_get_template( '/plugin-info/features.php', $view_vars );
229
- }
230
- }
231
-
232
- $data->is_paid = ! $is_free;
233
- $data->external = ! $is_wordpress_org;
234
-
235
- return $data;
236
- }
237
-
238
- /**
239
- * @author Vova Feldman (@svovaf)
240
- * @since 1.1.7
241
- *
242
- * @param FS_Plugin_Plan $plan
243
- *
244
- * @return string
245
- */
246
- private function get_billing_cycle( FS_Plugin_Plan $plan ) {
247
- $billing_cycle = null;
248
-
249
- if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) {
250
- $pricing = $plan->pricing[0];
251
- if ( isset( $pricing->annual_price ) ) {
252
- $billing_cycle = 'annual';
253
- } else if ( isset( $pricing->monthly_price ) ) {
254
- $billing_cycle = 'monthly';
255
- } else if ( isset( $pricing->lifetime_price ) ) {
256
- $billing_cycle = 'lifetime';
257
- }
258
- } else {
259
- foreach ( $plan->pricing as $pricing ) {
260
- if ( isset( $pricing->annual_price ) ) {
261
- $billing_cycle = 'annual';
262
- } else if ( isset( $pricing->monthly_price ) ) {
263
- $billing_cycle = 'monthly';
264
- } else if ( isset( $pricing->lifetime_price ) ) {
265
- $billing_cycle = 'lifetime';
266
- }
267
-
268
- if ( ! is_null( $billing_cycle ) ) {
269
- break;
270
- }
271
- }
272
- }
273
-
274
- return $billing_cycle;
275
- }
276
-
277
- /**
278
- * @author Vova Feldman (@svovaf)
279
- * @since 1.1.7
280
- *
281
- * @param FS_Plugin_Plan $plan
282
- * @param FS_Pricing $pricing
283
- *
284
- * @return float|null|string
285
- */
286
- private function get_price_tag( FS_Plugin_Plan $plan, FS_Pricing $pricing ) {
287
- $price_tag = '';
288
- if ( isset( $pricing->annual_price ) ) {
289
- $price_tag = $pricing->annual_price . ( $plan->is_block_features ? ' / year' : '' );
290
- } else if ( isset( $pricing->monthly_price ) ) {
291
- $price_tag = $pricing->monthly_price . ' / mo';
292
- } else if ( isset( $pricing->lifetime_price ) ) {
293
- $price_tag = $pricing->lifetime_price;
294
- }
295
-
296
- return '$' . $price_tag;
297
- }
298
-
299
- /**
300
- * @author Vova Feldman (@svovaf)
301
- * @since 1.1.7
302
- *
303
- * @param object $api
304
- * @param FS_Plugin_Plan|null $plan
305
- *
306
- * @return string
307
- */
308
- private function get_plugin_cta( $api, $plan = null ) {
309
- if ( ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) {
310
-
311
- if ( ! empty( $api->checkout_link ) && isset( $api->plans ) && 0 < is_array( $api->plans ) ) {
312
- if ( is_null( $plan ) ) {
313
- foreach ($api->plans as $p) {
314
- if (!empty($p->pricing)) {
315
- $plan = $p;
316
- break;
317
- }
318
- }
319
- }
320
-
321
- return ' <a class="button button-primary right" href="' . $this->_fs->addon_checkout_url(
322
- $plan->plugin_id,
323
- $plan->pricing[0]->id,
324
- $this->get_billing_cycle( $plan ),
325
- $plan->has_trial()
326
- ) . '" target="_parent">' .
327
- ( ! $plan->has_trial() ?
328
- fs_text_x_inline( 'Purchase', 'verb', 'purchase', $api->slug ) :
329
- sprintf(
330
- /* translators: %s: N-days trial */
331
- fs_text_inline( 'Start my free %s', 'start-free-x', $api->slug ),
332
- $this->get_trial_period( $plan )
333
- )
334
- ) .
335
- '</a>';
336
-
337
- // @todo Add Cart concept.
338
- // echo ' <a class="button right" href="' . $status['url'] . '" target="_parent">' . __( 'Add to Cart' ) . '</a>';
339
-
340
- } else if ( ! empty( $api->download_link ) ) {
341
- $status = install_plugin_install_status( $api );
342
-
343
- // Hosted on WordPress.org.
344
- switch ( $status['status'] ) {
345
- case 'install':
346
- if ( $api->external &&
347
- $this->_fs->is_org_repo_compliant() ||
348
- ! $this->_fs->is_premium()
349
- ) {
350
- /**
351
- * Add-on hosted on Freemius, not yet installed, and core
352
- * plugin is wordpress.org compliant. Therefore, require a download
353
- * since installing external plugins is not allowed by the wp.org guidelines.
354
- */
355
- return ' <a class="button button-primary right" href="' . esc_url( $api->download_link ) . '" target="_blank">' . fs_esc_html_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $api->slug ) . '</a>';
356
- } else {
357
- if ( $status['url'] ) {
358
- return '<a class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . fs_esc_html_inline( 'Install Now', 'install-now', $api->slug ) . '</a>';
359
- }
360
- }
361
- break;
362
- case 'update_available':
363
- if ( $status['url'] ) {
364
- return '<a class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . fs_text_inline( 'Install Update Now', 'install-update-now', $api->slug ) . '</a>';
365
- }
366
- break;
367
- case 'newer_installed':
368
- return '<a class="button button-primary right disabled">' . sprintf( fs_text_inline( 'Newer Version (%s) Installed', 'newer-installed', $api->slug ), $status['version'] ) . '</a>';
369
- break;
370
- case 'latest_installed':
371
- return '<a class="button button-primary right disabled">' . fs_text_inline( 'Latest Version Installed', 'latest-installed', $api->slug ) . '</a>';
372
- break;
373
- }
374
-
375
- }
376
- }
377
-
378
- return '';
379
- }
380
-
381
- /**
382
- * @author Vova Feldman (@svovaf)
383
- * @since 1.1.7
384
- *
385
- * @param FS_Plugin_Plan $plan
386
- *
387
- * @return string
388
- */
389
- private function get_trial_period( $plan ) {
390
- $trial_period = (int) $plan->trial_period;
391
-
392
- switch ( $trial_period ) {
393
- case 30:
394
- return 'month';
395
- case 60:
396
- return '2 months';
397
- default:
398
- return "{$plan->trial_period} days";
399
- }
400
- }
401
-
402
- /**
403
- * Display plugin information in dialog box form.
404
- *
405
- * Based on core install_plugin_information() function.
406
- *
407
- * @author Vova Feldman (@svovaf)
408
- * @since 1.0.6
409
- */
410
- function install_plugin_information() {
411
- global $tab;
412
-
413
- if ( empty( $_REQUEST['plugin'] ) ) {
414
- return;
415
- }
416
-
417
- $args = array(
418
- 'slug' => wp_unslash( $_REQUEST['plugin'] ),
419
- 'is_ssl' => is_ssl(),
420
- 'fields' => array(
421
- 'banners' => true,
422
- 'reviews' => true,
423
- 'downloaded' => false,
424
- 'active_installs' => true
425
- )
426
- );
427
-
428
- if ( is_array( $args ) ) {
429
- $args = (object) $args;
430
- }
431
-
432
- if ( ! isset( $args->per_page ) ) {
433
- $args->per_page = 24;
434
- }
435
-
436
- if ( ! isset( $args->locale ) ) {
437
- $args->locale = get_locale();
438
- }
439
-
440
- $api = apply_filters( 'fs_plugins_api', false, 'plugin_information', $args );
441
-
442
- if ( is_wp_error( $api ) ) {
443
- wp_die( $api );
444
- }
445
-
446
- $plugins_allowedtags = array(
447
- 'a' => array(
448
- 'href' => array(),
449
- 'title' => array(),
450
- 'target' => array(),
451
- // Add image style for screenshots.
452
- 'class' => array()
453
- ),
454
- 'style' => array(),
455
- 'abbr' => array( 'title' => array() ),
456
- 'acronym' => array( 'title' => array() ),
457
- 'code' => array(),
458
- 'pre' => array(),
459
- 'em' => array(),
460
- 'strong' => array(),
461
- 'div' => array( 'class' => array() ),
462
- 'span' => array( 'class' => array() ),
463
- 'p' => array(),
464
- 'ul' => array(),
465
- 'ol' => array(),
466
- 'li' => array( 'class' => array() ),
467
- 'i' => array( 'class' => array() ),
468
- 'h1' => array(),
469
- 'h2' => array(),
470
- 'h3' => array(),
471
- 'h4' => array(),
472
- 'h5' => array(),
473
- 'h6' => array(),
474
- 'img' => array( 'src' => array(), 'class' => array(), 'alt' => array() ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  // 'table' => array(),
476
  // 'td' => array(),
477
  // 'tr' => array(),
478
  // 'th' => array(),
479
  // 'thead' => array(),
480
  // 'tbody' => array(),
481
- );
482
-
483
- $plugins_section_titles = array(
484
- 'description' => fs_text_x_inline( 'Description', 'Plugin installer section title', 'description', $api->slug ),
485
- 'installation' => fs_text_x_inline( 'Installation', 'Plugin installer section title', 'installation', $api->slug ),
486
- 'faq' => fs_text_x_inline( 'FAQ', 'Plugin installer section title', 'faq', $api->slug ),
487
- 'screenshots' => fs_text_inline( 'Screenshots', 'screenshots', $api->slug ),
488
- 'changelog' => fs_text_x_inline( 'Changelog', 'Plugin installer section title', 'changelog', $api->slug ),
489
- 'reviews' => fs_text_x_inline( 'Reviews', 'Plugin installer section title', 'reviews', $api->slug ),
490
- 'other_notes' => fs_text_x_inline( 'Other Notes', 'Plugin installer section title', 'other-notes', $api->slug ),
491
- );
492
-
493
- // Sanitize HTML
494
  // foreach ( (array) $api->sections as $section_name => $content ) {
495
  // $api->sections[$section_name] = wp_kses( $content, $plugins_allowedtags );
496
  // }
497
 
498
- foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) {
499
- if ( isset( $api->$key ) ) {
500
- $api->$key = wp_kses( $api->$key, $plugins_allowedtags );
501
- }
502
- }
503
 
504
- // Add after $api->slug is ready.
505
- $plugins_section_titles['features'] = fs_text_x_inline( 'Features & Pricing', 'Plugin installer section title', 'features-and-pricing', $api->slug );
506
 
507
- $_tab = esc_attr( $tab );
508
 
509
- $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English.
510
- if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) {
511
- $section_titles = array_keys( (array) $api->sections );
512
- $section = array_shift( $section_titles );
513
- }
514
 
515
- iframe_header( fs_text_inline( 'Plugin Install', 'plugin-install', $api->slug ) );
516
 
517
- $_with_banner = '';
518
 
519
  // var_dump($api->banners);
520
- if ( ! empty( $api->banners ) && ( ! empty( $api->banners['low'] ) || ! empty( $api->banners['high'] ) ) ) {
521
- $_with_banner = 'with-banner';
522
- $low = empty( $api->banners['low'] ) ? $api->banners['high'] : $api->banners['low'];
523
- $high = empty( $api->banners['high'] ) ? $api->banners['low'] : $api->banners['high'];
524
- ?>
525
- <style type="text/css">
526
- #plugin-information-title.with-banner
527
- {
528
- background-image: url( <?php echo esc_url( $low ); ?> );
529
- }
530
-
531
- @media only screen and ( -webkit-min-device-pixel-ratio: 1.5 )
532
- {
533
- #plugin-information-title.with-banner
534
- {
535
- background-image: url( <?php echo esc_url( $high ); ?> );
536
- }
537
- }
538
- </style>
539
- <?php
540
- }
541
-
542
- echo '<div id="plugin-information-scrollable">';
543
- echo "<div id='{$_tab}-title' class='{$_with_banner}'><div class='vignette'></div><h2>{$api->name}</h2></div>";
544
- echo "<div id='{$_tab}-tabs' class='{$_with_banner}'>\n";
545
-
546
- foreach ( (array) $api->sections as $section_name => $content ) {
547
- if ( 'reviews' === $section_name && ( empty( $api->ratings ) || 0 === array_sum( (array) $api->ratings ) ) ) {
548
- continue;
549
- }
550
-
551
- if ( isset( $plugins_section_titles[ $section_name ] ) ) {
552
- $title = $plugins_section_titles[ $section_name ];
553
- } else {
554
- $title = ucwords( str_replace( '_', ' ', $section_name ) );
555
- }
556
-
557
- $class = ( $section_name === $section ) ? ' class="current"' : '';
558
- $href = add_query_arg( array( 'tab' => $tab, 'section' => $section_name ) );
559
- $href = esc_url( $href );
560
- $san_section = esc_attr( $section_name );
561
- echo "\t<a name='$san_section' href='$href' $class>$title</a>\n";
562
- }
563
-
564
- echo "</div>\n";
565
-
566
- ?>
567
- <div id="<?php echo $_tab; ?>-content" class='<?php echo $_with_banner; ?>'>
568
- <div class="fyi">
569
- <?php if ( $api->is_paid ) : ?>
570
- <?php if ( isset( $api->plans ) ) : ?>
571
- <div class="plugin-information-pricing">
572
- <?php foreach ( $api->plans as $plan ) : ?>
573
- <?php
574
- if ( empty( $plan->pricing ) ) {
575
- continue;
576
- }
577
-
578
- /**
579
- * @var FS_Plugin_Plan $plan
580
- */
581
- ?>
582
- <?php $first_pricing = $plan->pricing[0] ?>
583
- <?php $is_multi_cycle = $first_pricing->is_multi_cycle() ?>
584
- <div class="fs-plan<?php if ( ! $is_multi_cycle ) {
585
- echo ' fs-single-cycle';
586
- } ?>" data-plan-id="<?php echo $plan->id ?>">
587
- <h3 data-plan="<?php echo $plan->id ?>"><?php echo esc_html( sprintf( fs_text_x_inline( '%s Plan', 'e.g. Professional Plan', 'x-plan', $api->slug ), $plan->title ) ) ?></h3>
588
- <?php $has_annual = $first_pricing->has_annual() ?>
589
- <?php $has_monthly = $first_pricing->has_monthly() ?>
590
- <div class="nav-tab-wrapper">
591
- <?php $billing_cycles = array( 'monthly', 'annual', 'lifetime' ) ?>
592
- <?php $i = 0;
593
- foreach ( $billing_cycles as $cycle ) : ?>
594
- <?php $prop = "{$cycle}_price";
595
- if ( isset( $first_pricing->{$prop} ) ) : ?>
596
- <?php $is_featured = ( 'annual' === $cycle && $is_multi_cycle ) ?>
597
- <?php
598
- $prices = array();
599
- foreach ( $plan->pricing as $pricing ) {
600
- if ( isset( $pricing->{$prop} ) ) {
601
- $prices[] = array(
602
- 'id' => $pricing->id,
603
- 'licenses' => $pricing->licenses,
604
- 'price' => $pricing->{$prop}
605
- );
606
- }
607
- }
608
- ?>
609
- <a class="nav-tab" data-billing-cycle="<?php echo $cycle ?>"
610
- data-pricing="<?php echo esc_attr( json_encode( $prices ) ) ?>">
611
- <?php if ( $is_featured ) : ?>
612
- <label>&#9733; <?php fs_esc_html_echo_x_inline( 'Best', 'e.g. the best product', 'best', $api->slug ) ?> &#9733;</label>
613
- <?php endif ?>
614
- <?php
615
- switch ($cycle)
616
- {
617
- case 'monthly':
618
- fs_esc_html_echo_x_inline( 'Monthly', 'as every month', 'monthly', $api->slug );
619
- break;
620
- case 'annual':
621
- fs_esc_html_echo_x_inline( 'Annual', 'as once a year', 'annual', $api->slug );
622
- break;
623
- case 'lifetime':
624
- fs_esc_html_echo_inline( 'Lifetime', 'lifetime', $api->slug );
625
- break;
626
- }
627
- ?>
628
- </a>
629
- <?php endif ?>
630
- <?php $i ++; endforeach ?>
631
- <?php wp_enqueue_script( 'jquery' ) ?>
632
- <script type="text/javascript">
633
- (function ($, undef) {
634
- var
635
- _formatBillingFrequency = function (cycle) {
636
- switch (cycle) {
637
- case 'monthly':
638
- return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug), fs_text_x_inline( 'Monthly', 'as every month', 'monthly', $api->slug ) ) ?>';
639
- case 'annual':
640
- return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug), fs_text_x_inline( 'Annually', 'as once a year', 'annually', $api->slug ) ) ?>';
641
- case 'lifetime':
642
- return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug), fs_text_x_inline( 'Once', 'as once a year', 'once', $api->slug ) ) ?>';
643
- }
644
- },
645
- _formatLicensesTitle = function (pricing) {
646
- switch (pricing.licenses) {
647
- case 1:
648
- return '<?php fs_esc_attr_echo_inline( 'Single Site License', 'license-single-site', $api->slug ) ?>';
649
- case null:
650
- return '<?php fs_esc_attr_echo_inline( 'Unlimited Licenses', 'license-unlimited', $api->slug ) ?>';
651
- default:
652
- return '<?php fs_esc_attr_echo_inline( 'Up to %s Sites', 'license-x-sites', $api->slug ) ?>'.replace('%s', pricing.licenses);
653
- }
654
- },
655
- _formatPrice = function (pricing, cycle, multipleLicenses) {
656
- if (undef === multipleLicenses)
657
- multipleLicenses = true;
658
-
659
- var priceCycle;
660
- switch (cycle) {
661
- case 'monthly':
662
- priceCycle = ' / <?php fs_echo_x_inline( 'mo', 'as monthly period', 'mo', $api->slug ) ?>';
663
- break;
664
- case 'lifetime':
665
- priceCycle = '';
666
- break;
667
- case 'annual':
668
- default:
669
- priceCycle = ' / <?php fs_echo_x_inline('year', 'as annual period', 'year', $api->slug) ?>';
670
- break;
671
- }
672
-
673
- if (!multipleLicenses && 1 == pricing.licenses) {
674
- return '$' + pricing.price + priceCycle;
675
- }
676
-
677
- return _formatLicensesTitle(pricing) + ' - <var class="fs-price">$' + pricing.price + priceCycle + '</var>';
678
- },
679
- _checkoutUrl = function (plan, pricing, cycle) {
680
- return '<?php echo esc_url_raw(remove_query_arg('billing_cycle', add_query_arg(array('plugin_id' => $plan->plugin_id), $api->checkout_link))) ?>' +
681
- '&plan_id=' + plan +
682
- '&pricing_id=' + pricing +
683
- '&billing_cycle=' + cycle<?php if ($plan->has_trial()) { echo " + '&trial=true'"; }?>;
684
- },
685
- _updateCtaUrl = function (plan, pricing, cycle) {
686
- $('.plugin-information-pricing .button, #plugin-information-footer .button').attr('href', _checkoutUrl(plan, pricing, cycle));
687
- };
688
-
689
- $(document).ready(function () {
690
- var $plan = $('.plugin-information-pricing .fs-plan[data-plan-id=<?php echo $plan->id ?>]');
691
- $plan.find('input[type=radio]').live('click', function () {
692
- _updateCtaUrl(
693
- $plan.attr('data-plan-id'),
694
- $(this).val(),
695
- $plan.find('.nav-tab-active').attr('data-billing-cycle')
696
- );
697
-
698
- $plan.find('.fs-trial-terms .fs-price').html(
699
- $(this).parents('label').find('.fs-price').html()
700
- );
701
- });
702
-
703
- $plan.find('.nav-tab').click(function () {
704
- if ($(this).hasClass('nav-tab-active'))
705
- return;
706
-
707
- var $this = $(this),
708
- billingCycle = $this.attr('data-billing-cycle'),
709
- pricing = JSON.parse($this.attr('data-pricing')),
710
- $pricesList = $this.parents('.fs-plan').find('.fs-pricing-body .fs-licenses'),
711
- html = '';
712
-
713
- // Un-select previously selected tab.
714
- $plan.find('.nav-tab').removeClass('nav-tab-active');
715
-
716
- // Select current tab.
717
- $this.addClass('nav-tab-active');
718
-
719
- // Render licenses prices.
720
- if (1 == pricing.length) {
721
- html = '<li><label><?php echo fs_esc_attr_x_inline( 'Price', 'noun', 'price', $api->slug ) ?>: ' + _formatPrice(pricing[0], billingCycle, false) + '</label></li>';
722
- } else {
723
- for (var i = 0; i < pricing.length; i++) {
724
- html += '<li><label><input name="pricing-<?php echo $plan->id ?>" type="radio" value="' + pricing[i].id + '">' + _formatPrice(pricing[i], billingCycle) + '</label></li>';
725
- }
726
- }
727
- $pricesList.html(html);
728
-
729
- if (1 < pricing.length) {
730
- // Select first license option.
731
- $pricesList.find('li:first input').click();
732
- }
733
- else {
734
- _updateCtaUrl(
735
- $plan.attr('data-plan-id'),
736
- pricing[0].id,
737
- billingCycle
738
- );
739
- }
740
-
741
- // Update billing frequency.
742
- $plan.find('.fs-billing-frequency').html(_formatBillingFrequency(billingCycle));
743
-
744
- if ('annual' === billingCycle) {
745
- $plan.find('.fs-annual-discount').show();
746
- } else {
747
- $plan.find('.fs-annual-discount').hide();
748
- }
749
- });
750
-
751
- <?php if ( $has_annual ) : ?>
752
- // Select annual by default.
753
- $plan.find('.nav-tab[data-billing-cycle=annual]').click();
754
- <?php else : ?>
755
- // Select first tab.
756
- $plan.find('.nav-tab:first').click();
757
- <?php endif ?>
758
- });
759
- }(jQuery));
760
- </script>
761
- </div>
762
- <div class="fs-pricing-body">
763
- <span class="fs-billing-frequency"></span>
764
- <?php $annual_discount = ( $has_annual && $has_monthly ) ? $plan->pricing[0]->annual_discount_percentage() : 0 ?>
765
- <?php if ( $annual_discount > 0 ) : ?>
766
- <span
767
- class="fs-annual-discount"><?php printf(
768
- /* translators: %s: Discount (e.g. discount of $5 or 10%) */
769
- fs_esc_html_inline( 'Save %s', 'save-x', $api->slug ), $annual_discount . '%' ) ?></span>
770
- <?php endif ?>
771
- <ul class="fs-licenses">
772
- </ul>
773
- <?php echo $this->get_plugin_cta( $api, $plan ) ?>
774
- <div style="clear:both"></div>
775
- <?php if ( $plan->has_trial() ) : ?>
776
- <?php $trial_period = $this->get_trial_period( $plan ) ?>
777
- <ul class="fs-trial-terms">
778
- <li>
779
- <i class="dashicons dashicons-yes"></i><?php echo esc_html( sprintf( fs_text_inline( 'No commitment for %s - cancel anytime', 'no-commitment-x', $api->slug ), $trial_period ) ) ?>
780
- </li>
781
- <li>
782
- <i class="dashicons dashicons-yes"></i><?php printf( esc_html( fs_text_inline( 'After your free %s, pay as little as %s', 'after-x-pay-as-little-y', $api->slug ) ), $trial_period, '<var class="fs-price">' . $this->get_price_tag( $plan, $plan->pricing[0] ) . '</var>' ) ?>
783
- </li>
784
- </ul>
785
- <?php endif ?>
786
- </div>
787
- </div>
788
- </div>
789
- <?php endforeach ?>
790
- <?php endif ?>
791
- <?php endif ?>
792
- <div>
793
- <h3><?php fs_echo_inline( 'Details', 'details', $api->slug ) ?></h3>
794
- <ul>
795
- <?php if ( ! empty( $api->version ) ) { ?>
796
- <li><strong><?php fs_esc_html_echo_x_inline( 'Version', 'product version', 'version', $api->slug ); ?>:</strong> <?php echo $api->version; ?></li>
797
- <?php
798
- }
799
- if ( ! empty( $api->author ) ) {
800
- ?>
801
- <li>
802
- <strong><?php fs_echo_x_inline( 'Author', 'as the plugin author', 'author', $api->slug ); ?>:</strong> <?php echo links_add_target( $api->author, '_blank' ); ?>
803
- </li>
804
- <?php
805
- }
806
- if ( ! empty( $api->last_updated ) ) {
807
- ?>
808
- <li><strong><?php fs_echo_inline( 'Last Updated', 'last-updated', $api->slug ); ?>:</strong> <span
809
- title="<?php echo $api->last_updated; ?>">
 
 
 
 
 
 
 
810
  <?php echo esc_html( sprintf(
811
- /* translators: %s: time period (e.g. "2 hours" ago) */
812
- fs_text_x_inline( '%s ago', 'x-ago', $api->slug ),
813
- human_time_diff( strtotime( $api->last_updated ) )
814
- ) ) ?>
815
  </span></li>
816
- <?php
817
- }
818
- if ( ! empty( $api->requires ) ) {
819
- ?>
820
- <li>
821
- <strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?>:</strong> <?php echo esc_html( sprintf( fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires ) ) ?>
822
- </li>
823
- <?php
824
- }
825
- if ( ! empty( $api->tested ) ) {
826
- ?>
827
- <li><strong><?php fs_esc_html_echo_inline( 'Compatible up to', 'compatible-up-to', $api->slug ); ?>:</strong> <?php echo $api->tested; ?>
828
- </li>
829
- <?php
830
- }
831
- if ( ! empty( $api->downloaded ) ) {
832
- ?>
833
- <li>
834
- <strong><?php fs_esc_html_echo_inline( 'Downloaded', 'downloaded', $api->slug ) ?>:</strong> <?php echo esc_html( sprintf(
835
- ( ( 1 == $api->downloaded ) ?
836
- /* translators: %s: 1 or One (Number of times downloaded) */
837
- fs_text_inline( '%s time', 'x-time', $api->slug ) :
838
- /* translators: %s: Number of times downloaded */
839
- fs_text_inline( '%s times', 'x-times', $api->slug )
840
- ),
841
- number_format_i18n( $api->downloaded )
842
- ) ); ?>
843
- </li>
844
- <?php
845
- }
846
- if ( ! empty( $api->slug ) && empty( $api->external ) ) {
847
- ?>
848
- <li><a target="_blank"
849
- href="https://wordpress.org/plugins/<?php echo $api->slug; ?>/"><?php fs_esc_html_echo_inline( 'WordPress.org Plugin Page', 'wp-org-plugin-page', $api->slug ) ?> &#187;</a>
850
- </li>
851
- <?php
852
- }
853
- if ( ! empty( $api->homepage ) ) {
854
- ?>
855
- <li><a target="_blank"
856
- href="<?php echo esc_url( $api->homepage ); ?>"><?php fs_esc_html_echo_inline( 'Plugin Homepage', 'plugin-homepage', $api->slug ) ?> &#187;</a>
857
- </li>
858
- <?php
859
- }
860
- if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) {
861
- ?>
862
- <li><a target="_blank"
863
- href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_esc_html_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?> &#187;</a>
864
- </li>
865
- <?php } ?>
866
- </ul>
867
- </div>
868
- <?php if ( ! empty( $api->rating ) ) { ?>
869
- <h3><?php fs_echo_inline( 'Average Rating', 'average-rating', $api->slug ); ?></h3>
870
- <?php wp_star_rating( array(
871
- 'rating' => $api->rating,
872
- 'type' => 'percent',
873
- 'number' => $api->num_ratings
874
- ) ); ?>
875
- <small>(<?php echo esc_html( sprintf(
876
- fs_text_inline( 'based on %s', 'based-on-x', $api->slug ),
877
- sprintf(
878
- ( ( 1 == $api->num_ratings ) ?
879
- /* translators: %s: 1 or One */
880
- fs_text_inline( '%s rating', 'x-rating', $api->slug ) :
881
- /* translators: %s: Number larger than 1 */
882
- fs_text_inline( '%s ratings', 'x-ratings', $api->slug )
883
- ),
884
- number_format_i18n( $api->num_ratings )
885
- ) ) ) ?>)</small>
886
- <?php
887
- }
888
-
889
- if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) {
890
- foreach ( $api->ratings as $key => $ratecount ) {
891
- // Avoid div-by-zero.
892
- $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0;
893
- $stars_label = sprintf(
894
- ( ( 1 == $key ) ?
895
- /* translators: %s: 1 or One */
896
- fs_text_inline( '%s star', 'x-star', $api->slug ) :
897
- /* translators: %s: Number larger than 1 */
898
- fs_text_inline( '%s stars', 'x-stars', $api->slug )
899
- ),
900
- number_format_i18n( $key )
901
- );
902
- ?>
903
- <div class="counter-container">
 
 
 
 
 
 
 
 
904
  <span class="counter-label"><a
905
- href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
906
- target="_blank"
907
- title="<?php echo esc_attr( sprintf(
908
- /* translators: %s: # of stars (e.g. 5 stars) */
909
- fs_text_inline( 'Click to see reviews that provided a rating of %s', 'click-to-reviews', $api->slug ),
910
- $stars_label
911
- ) ) ?>"><?php echo $stars_label ?></a></span>
912
- <span class="counter-back">
913
  <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
914
  </span>
915
- <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
916
- </div>
917
- <?php
918
- }
919
- }
920
- if ( ! empty( $api->contributors ) ) {
921
- ?>
922
- <h3><?php fs_echo_inline( 'Contributors', 'contributors', $api->slug ); ?></h3>
923
- <ul class="contributors">
924
- <?php
925
- foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) {
926
- if ( empty( $contrib_username ) && empty( $contrib_profile ) ) {
927
- continue;
928
- }
929
- if ( empty( $contrib_username ) ) {
930
- $contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile );
931
- }
932
- $contrib_username = sanitize_user( $contrib_username );
933
- if ( empty( $contrib_profile ) ) {
934
- echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</li>";
935
- } else {
936
- echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
937
- }
938
- }
939
- ?>
940
- </ul>
941
- <?php if ( ! empty( $api->donate_link ) ) { ?>
942
- <a target="_blank"
943
- href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?> &#187;</a>
944
- <?php } ?>
945
- <?php } ?>
946
- </div>
947
- <div id="section-holder" class="wrap">
948
- <?php
949
- if ( ! empty( $api->tested ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->tested ) ), $api->tested, '>' ) ) {
950
- echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '</p></div>';
951
- } else if ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) {
952
- echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '</p></div>';
953
- }
954
-
955
- foreach ( (array) $api->sections as $section_name => $content ) {
956
- $content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' );
957
- $content = links_add_target( $content, '_blank' );
958
-
959
- $san_section = esc_attr( $section_name );
960
-
961
- $display = ( $section_name === $section ) ? 'block' : 'none';
962
-
963
- if ( 'description' === $section_name &&
964
- ( ( ! $api->external && $api->wp_org_missing ) ||
965
- ( $api->external && $api->fs_missing ) )
966
- ) {
967
- $missing_notice = array(
968
- 'type' => 'error',
969
- 'id' => md5( microtime() ),
970
- 'message' => $api->is_paid ?
971
- fs_text_inline( 'Paid add-on must be deployed to Freemius.', 'paid-addon-not-deployed', $api->slug ) :
972
- fs_text_inline( 'Add-on must be deployed to WordPress.org or Freemius.', 'free-addon-not-deployed', $api->slug ),
973
- );
974
- fs_require_template( 'admin-notice.php', $missing_notice );
975
- }
976
- echo "\t<div id='section-{$san_section}' class='section' style='display: {$display};'>\n";
977
- echo $content;
978
- echo "\t</div>\n";
979
- }
980
- echo "</div>\n";
981
- echo "</div>\n";
982
- echo "</div>\n"; // #plugin-information-scrollable
983
- echo "<div id='$tab-footer'>\n";
984
-
985
- echo $this->get_plugin_cta( $api );
986
-
987
- echo "</div>\n";
988
-
989
- iframe_footer();
990
- exit;
991
- }
992
- }
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.6
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class FS_Plugin_Info_Dialog
15
+ *
16
+ * @author Vova Feldman (@svovaf)
17
+ * @since 1.1.7
18
+ */
19
+ class FS_Plugin_Info_Dialog {
20
+ /**
21
+ * @since 1.1.7
22
+ *
23
+ * @var FS_Logger
24
+ */
25
+ private $_logger;
26
+
27
+ /**
28
+ * @since 1.1.7
29
+ *
30
+ * @var Freemius
31
+ */
32
+ private $_fs;
33
+
34
+ function __construct( Freemius $fs ) {
35
+ $this->_fs = $fs;
36
+
37
+ $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $fs->get_slug() . '_info', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
38
+
39
+ // Remove default plugin information action.
40
+ remove_all_actions( 'install_plugins_pre_plugin-information' );
41
+
42
+ // Override action with custom plugins function for add-ons.
43
+ add_action( 'install_plugins_pre_plugin-information', array( &$this, 'install_plugin_information' ) );
44
+
45
+ // Override request for plugin information for Add-ons.
46
+ add_filter(
47
+ 'fs_plugins_api',
48
+ array( &$this, '_get_addon_info_filter' ),
49
+ WP_FS__DEFAULT_PRIORITY, 3 );
50
+ }
51
+
52
+ /**
53
+ * Generate add-on plugin information.
54
+ *
55
+ * @author Vova Feldman (@svovaf)
56
+ * @since 1.0.6
57
+ *
58
+ * @param array $data
59
+ * @param string $action
60
+ * @param object|null $args
61
+ *
62
+ * @return array|null
63
+ */
64
+ function _get_addon_info_filter( $data, $action = '', $args = null ) {
65
+ $this->_logger->entrance();
66
+
67
+ $parent_plugin_id = fs_request_get( 'parent_plugin_id', false );
68
+
69
+ if ( $this->_fs->get_id() != $parent_plugin_id ||
70
+ ( 'plugin_information' !== $action ) ||
71
+ ! isset( $args->slug )
72
+ ) {
73
+ return $data;
74
+ }
75
+
76
+ // Find add-on by slug.
77
+ $selected_addon = $this->_fs->get_addon_by_slug( $args->slug, WP_FS__DEV_MODE );
78
+
79
+ if ( false === $selected_addon ) {
80
+ return $data;
81
+ }
82
+
83
+ if ( ! isset( $selected_addon->info ) ) {
84
+ // Setup some default info.
85
+ $selected_addon->info = new stdClass();
86
+ $selected_addon->info->selling_point_0 = 'Selling Point 1';
87
+ $selected_addon->info->selling_point_1 = 'Selling Point 2';
88
+ $selected_addon->info->selling_point_2 = 'Selling Point 3';
89
+ $selected_addon->info->description = '<p>Tell your users all about your add-on</p>';
90
+ }
91
+
92
+ fs_enqueue_local_style( 'fs_addons', '/admin/add-ons.css' );
93
+
94
+ $data = $args;
95
+
96
+ $has_free_plan = false;
97
+ $has_paid_plan = false;
98
+
99
+ // Load add-on pricing.
100
+ $has_pricing = false;
101
+ $has_features = false;
102
+ $plans = false;
103
+
104
+ $result = $this->_fs->get_api_plugin_scope()->get( "/addons/{$selected_addon->id}/pricing.json?type=visible" );
105
+
106
+ if ( ! isset( $result->error ) ) {
107
+ $plans = $result->plans;
108
+
109
+ if ( is_array( $plans ) ) {
110
+ for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
111
+ $pricing = isset( $plans[ $i ]->pricing ) ? $plans[ $i ]->pricing : null;
112
+ $features = isset( $plans[ $i ]->features ) ? $plans[ $i ]->features : null;
113
+
114
+ $plans[ $i ] = new FS_Plugin_Plan( $plans[ $i ] );
115
+ $plan = $plans[ $i ];
116
+
117
+ if ( 'free' == $plans[ $i ]->name ||
118
+ ! is_array( $pricing ) ||
119
+ 0 == count( $pricing )
120
+ ) {
121
+ $has_free_plan = true;
122
+ }
123
+
124
+ if ( is_array( $pricing ) && 0 < count( $pricing ) ) {
125
+ $has_paid_plan = true;
126
+
127
+ foreach ( $pricing as &$prices ) {
128
+ $prices = new FS_Pricing( $prices );
129
+ }
130
+
131
+ $plan->pricing = $pricing;
132
+
133
+ $has_pricing = true;
134
+ }
135
+
136
+ if ( is_array( $features ) && 0 < count( $features ) ) {
137
+ $plan->features = $features;
138
+
139
+ $has_features = true;
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+ if ( ! $has_paid_plan && $selected_addon->is_wp_org_compliant ) {
146
+ $repo_data = FS_Plugin_Updater::_fetch_plugin_info_from_repository(
147
+ 'plugin_information', (object) array(
148
+ 'slug' => $selected_addon->slug,
149
+ 'is_ssl' => is_ssl(),
150
+ 'fields' => array(
151
+ 'banners' => true,
152
+ 'reviews' => true,
153
+ 'downloaded' => false,
154
+ 'active_installs' => true
155
+ )
156
+ ) );
157
+
158
+ if ( ! empty( $repo_data ) ) {
159
+ $data = $repo_data;
160
+ $data->wp_org_missing = false;
161
+ } else {
162
+ // Couldn't find plugin on .org.
163
+ $selected_addon->is_wp_org_compliant = false;
164
+
165
+ // Plugin is missing, not on Freemius nor WP.org.
166
+ $data->wp_org_missing = true;
167
+ }
168
+ } else {
169
+ $data->wp_org_missing = false;
170
+
171
+ // Fetch latest version from Freemius.
172
+ $latest = $this->_fs->_fetch_latest_version( $selected_addon->id );
173
+
174
+ if ( $has_paid_plan ) {
175
+ $data->checkout_link = $this->_fs->checkout_url();
176
+ }
177
+ if ( $has_free_plan ) {
178
+ $data->download_link = $this->_fs->_get_latest_download_local_url( $selected_addon->id );
179
+ }
180
+
181
+ $data->fs_missing = ( false === $latest );
182
+
183
+
184
+ // Fetch as much as possible info from local files.
185
+ $plugin_local_data = $this->_fs->get_plugin_data();
186
+ $data->name = $selected_addon->title;
187
+ $data->author = $plugin_local_data['Author'];
188
+ $view_vars = array( 'plugin' => $selected_addon );
189
+ $data->sections = array(
190
+ 'description' => fs_get_template( '/plugin-info/description.php', $view_vars ),
191
+ );
192
+
193
+ if ( ! empty( $selected_addon->info->banner_url ) ) {
194
+ $data->banners = array(
195
+ 'low' => $selected_addon->info->banner_url,
196
+ );
197
+ }
198
+
199
+ if ( ! empty( $selected_addon->info->screenshots ) ) {
200
+ $view_vars = array(
201
+ 'screenshots' => $selected_addon->info->screenshots,
202
+ 'plugin' => $selected_addon,
203
+ );
204
+ $data->sections['screenshots'] = fs_get_template( '/plugin-info/screenshots.php', $view_vars );
205
+ }
206
+
207
+ if ( is_object( $latest ) ) {
208
+ $data->version = $latest->version;
209
+ $data->last_updated = ! is_null( $latest->updated ) ? $latest->updated : $latest->created;
210
+ $data->requires = $latest->requires_platform_version;
211
+ $data->tested = $latest->tested_up_to_version;
212
+ } else {
213
+ // Add dummy version.
214
+ $data->version = '1.0.0';
215
+
216
+ // Add message to developer to deploy the plugin through Freemius.
217
+ }
218
+ }
219
+
220
+ if ( $has_pricing ) {
221
+ // Add plans to data.
222
+ $data->plans = $plans;
223
+
224
+ if ( $has_features ) {
225
+ $view_vars = array(
226
+ 'plans' => $plans,
227
+ 'plugin' => $selected_addon,
228
+ );
229
+ $data->sections['features'] = fs_get_template( '/plugin-info/features.php', $view_vars );
230
+ }
231
+ }
232
+
233
+ $data->has_free_plan = $has_free_plan;
234
+ $data->has_paid_plan = $has_paid_plan;
235
+ $data->is_paid = $has_paid_plan;
236
+ $data->is_wp_org_compliant = $selected_addon->is_wp_org_compliant;
237
+
238
+ return $data;
239
+ }
240
+
241
+ /**
242
+ * @author Vova Feldman (@svovaf)
243
+ * @since 1.1.7
244
+ *
245
+ * @param FS_Plugin_Plan $plan
246
+ *
247
+ * @return string
248
+ */
249
+ private function get_billing_cycle( FS_Plugin_Plan $plan ) {
250
+ $billing_cycle = null;
251
+
252
+ if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) {
253
+ $pricing = $plan->pricing[0];
254
+ if ( isset( $pricing->annual_price ) ) {
255
+ $billing_cycle = 'annual';
256
+ } else if ( isset( $pricing->monthly_price ) ) {
257
+ $billing_cycle = 'monthly';
258
+ } else if ( isset( $pricing->lifetime_price ) ) {
259
+ $billing_cycle = 'lifetime';
260
+ }
261
+ } else {
262
+ foreach ( $plan->pricing as $pricing ) {
263
+ if ( isset( $pricing->annual_price ) ) {
264
+ $billing_cycle = 'annual';
265
+ } else if ( isset( $pricing->monthly_price ) ) {
266
+ $billing_cycle = 'monthly';
267
+ } else if ( isset( $pricing->lifetime_price ) ) {
268
+ $billing_cycle = 'lifetime';
269
+ }
270
+
271
+ if ( ! is_null( $billing_cycle ) ) {
272
+ break;
273
+ }
274
+ }
275
+ }
276
+
277
+ return $billing_cycle;
278
+ }
279
+
280
+ /**
281
+ * @author Vova Feldman (@svovaf)
282
+ * @since 2.0.0
283
+ *
284
+ * @param FS_Plugin_Plan $plan
285
+ * @param FS_Pricing $pricing
286
+ *
287
+ * @return float|null|string
288
+ */
289
+ private function get_price_tag( FS_Plugin_Plan $plan, FS_Pricing $pricing ) {
290
+ $price_tag = '';
291
+ if ( isset( $pricing->annual_price ) ) {
292
+ $price_tag = $pricing->annual_price . ( $plan->is_block_features ? ' / year' : '' );
293
+ } else if ( isset( $pricing->monthly_price ) ) {
294
+ $price_tag = $pricing->monthly_price . ' / mo';
295
+ } else if ( isset( $pricing->lifetime_price ) ) {
296
+ $price_tag = $pricing->lifetime_price;
297
+ }
298
+
299
+ return '$' . $price_tag;
300
+ }
301
+
302
+ /**
303
+ * @author Vova Feldman (@svovaf)
304
+ * @since 1.1.7
305
+ *
306
+ * @param object $api
307
+ * @param FS_Plugin_Plan $plan
308
+ *
309
+ * @return string
310
+ */
311
+ private function get_checkout_cta( $api, $plan = null ) {
312
+ if ( empty( $api->checkout_link ) ||
313
+ ! isset( $api->plans ) ||
314
+ ! is_array( $api->plans ) ||
315
+ 0 == count( $api->plans )
316
+ ) {
317
+ return '';
318
+ }
319
+
320
+ if ( is_null( $plan ) ) {
321
+ foreach ( $api->plans as $p ) {
322
+ if ( ! empty( $p->pricing ) ) {
323
+ $plan = $p;
324
+ break;
325
+ }
326
+ }
327
+ }
328
+
329
+ return '<a class="button button-primary fs-checkout-button right" href="' . $this->_fs->addon_checkout_url(
330
+ $plan->plugin_id,
331
+ $plan->pricing[0]->id,
332
+ $this->get_billing_cycle( $plan ),
333
+ $plan->has_trial()
334
+ ) . '" target="_parent">' .
335
+ ( ! $plan->has_trial() ?
336
+ fs_text_x_inline( 'Purchase', 'verb', 'purchase', $api->slug ) :
337
+ sprintf(
338
+ /* translators: %s: N-days trial */
339
+ fs_text_inline( 'Start my free %s', 'start-free-x', $api->slug ),
340
+ $this->get_trial_period( $plan )
341
+ )
342
+ ) .
343
+ '</a>';
344
+ }
345
+
346
+ /**
347
+ * @author Vova Feldman (@svovaf)
348
+ * @since 2.0.0
349
+ *
350
+ * @param object $api
351
+ * @param bool $is_primary
352
+ *
353
+ * @return string
354
+ */
355
+ private function get_download_cta( $api, $is_primary = true ) {
356
+ if ( empty( $api->download_link ) ) {
357
+ return '';
358
+ }
359
+
360
+ $status = install_plugin_install_status( $api );
361
+
362
+ $has_paid_version = $api->has_paid_plan;
363
+
364
+ // Hosted on WordPress.org.
365
+ switch ( $status['status'] ) {
366
+ case 'install':
367
+ if ( $api->is_wp_org_compliant ||
368
+ ! $this->_fs->is_org_repo_compliant() ||
369
+ $this->_fs->is_premium()
370
+ ) {
371
+ /**
372
+ * Allow immediate installation if one of the following:
373
+ * 1. WordPress.org add-on.
374
+ * 2. The core module is NOT wp.org compliant.
375
+ * 3. The core module is running the premium version which is not wp.org compliant.
376
+ */
377
+ if ( $status['url'] ) {
378
+ return $this->get_cta(
379
+ ( $has_paid_version ?
380
+ fs_esc_html_inline( 'Install Free Version Now', 'install-free-version-now', $api->slug ) :
381
+ fs_esc_html_inline( 'Install Now', 'install-now', $api->slug ) ),
382
+ $is_primary,
383
+ false,
384
+ $status['url'],
385
+ '_parent'
386
+ );
387
+ }
388
+ }
389
+
390
+ return $this->get_cta(
391
+ ( $has_paid_version ?
392
+ fs_esc_html_x_inline( 'Download Latest Free Version', 'as download latest version', 'download-latest-free-version', $api->slug ) :
393
+ fs_esc_html_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $api->slug ) ),
394
+ $is_primary,
395
+ false,
396
+ esc_url( $api->download_link )
397
+ );
398
+ break;
399
+ case 'update_available':
400
+ if ( $status['url'] ) {
401
+ return $this->get_cta(
402
+ ( $has_paid_version ?
403
+ fs_esc_html_inline( 'Install Free Version Update Now', 'install-free-version-update-now', $api->slug ) :
404
+ fs_esc_html_inline( 'Install Update Now', 'install-update-now', $api->slug ) ),
405
+ $is_primary,
406
+ false,
407
+ $status['url'],
408
+ '_parent'
409
+ );
410
+ }
411
+ break;
412
+ case 'newer_installed':
413
+ return $this->get_cta(
414
+ ( $has_paid_version ?
415
+ esc_html( sprintf( fs_text_inline( 'Newer Free Version (%s) Installed', 'newer-free-installed', $api->slug ), $status['version'] ) ) :
416
+ esc_html( sprintf( fs_text_inline( 'Newer Version (%s) Installed', 'newer-installed', $api->slug ), $status['version'] ) ) ),
417
+ $is_primary,
418
+ true
419
+ );
420
+ break;
421
+ case 'latest_installed':
422
+ return $this->get_cta(
423
+ ( $has_paid_version ?
424
+ fs_esc_html_inline( 'Latest Free Version Installed', 'latest-free-installed', $api->slug ) :
425
+ fs_esc_html_inline( 'Latest Version Installed', 'latest-installed', $api->slug ) ),
426
+ $is_primary,
427
+ true
428
+ );
429
+ break;
430
+ }
431
+
432
+ return '';
433
+ }
434
+
435
+ /**
436
+ * Helper method to get a CTA button HTML.
437
+ *
438
+ * @author Vova Feldman (@svovaf)
439
+ * @since 2.0.0
440
+ *
441
+ * @param string $label
442
+ * @param bool $is_primary
443
+ * @param bool $is_disabled
444
+ * @param string $href
445
+ * @param string $target
446
+ *
447
+ * @return string
448
+ */
449
+ private function get_cta(
450
+ $label,
451
+ $is_primary = true,
452
+ $is_disabled = false,
453
+ $href = '',
454
+ $target = '_blank'
455
+ ) {
456
+ $classes = array();
457
+
458
+ if ( ! $is_primary ) {
459
+ $classes[] = 'left';
460
+ } else {
461
+ $classes[] = 'button-primary';
462
+ $classes[] = 'right';
463
+ }
464
+
465
+ if ( $is_disabled ) {
466
+ $classes[] = 'disabled';
467
+ }
468
+
469
+ return sprintf(
470
+ '<a %s class="button %s">%s</a>',
471
+ empty( $href ) ? '' : 'href="' . $href . '" target="' . $target . '"',
472
+ implode( ' ', $classes ),
473
+ $label
474
+ );
475
+ }
476
+
477
+ /**
478
+ * @author Vova Feldman (@svovaf)
479
+ * @since 1.1.7
480
+ *
481
+ * @param FS_Plugin_Plan $plan
482
+ *
483
+ * @return string
484
+ */
485
+ private function get_trial_period( $plan ) {
486
+ $trial_period = (int) $plan->trial_period;
487
+
488
+ switch ( $trial_period ) {
489
+ case 30:
490
+ return 'month';
491
+ case 60:
492
+ return '2 months';
493
+ default:
494
+ return "{$plan->trial_period} days";
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Display plugin information in dialog box form.
500
+ *
501
+ * Based on core install_plugin_information() function.
502
+ *
503
+ * @author Vova Feldman (@svovaf)
504
+ * @since 1.0.6
505
+ */
506
+ function install_plugin_information() {
507
+ global $tab;
508
+
509
+ if ( empty( $_REQUEST['plugin'] ) ) {
510
+ return;
511
+ }
512
+
513
+ $args = array(
514
+ 'slug' => wp_unslash( $_REQUEST['plugin'] ),
515
+ 'is_ssl' => is_ssl(),
516
+ 'fields' => array(
517
+ 'banners' => true,
518
+ 'reviews' => true,
519
+ 'downloaded' => false,
520
+ 'active_installs' => true
521
+ )
522
+ );
523
+
524
+ if ( is_array( $args ) ) {
525
+ $args = (object) $args;
526
+ }
527
+
528
+ if ( ! isset( $args->per_page ) ) {
529
+ $args->per_page = 24;
530
+ }
531
+
532
+ if ( ! isset( $args->locale ) ) {
533
+ $args->locale = get_locale();
534
+ }
535
+
536
+ $api = apply_filters( 'fs_plugins_api', false, 'plugin_information', $args );
537
+
538
+ if ( is_wp_error( $api ) ) {
539
+ wp_die( $api );
540
+ }
541
+
542
+ $plugins_allowedtags = array(
543
+ 'a' => array(
544
+ 'href' => array(),
545
+ 'title' => array(),
546
+ 'target' => array(),
547
+ // Add image style for screenshots.
548
+ 'class' => array()
549
+ ),
550
+ 'style' => array(),
551
+ 'abbr' => array( 'title' => array() ),
552
+ 'acronym' => array( 'title' => array() ),
553
+ 'code' => array(),
554
+ 'pre' => array(),
555
+ 'em' => array(),
556
+ 'strong' => array(),
557
+ 'div' => array( 'class' => array() ),
558
+ 'span' => array( 'class' => array() ),
559
+ 'p' => array(),
560
+ 'ul' => array(),
561
+ 'ol' => array(),
562
+ 'li' => array( 'class' => array() ),
563
+ 'i' => array( 'class' => array() ),
564
+ 'h1' => array(),
565
+ 'h2' => array(),
566
+ 'h3' => array(),
567
+ 'h4' => array(),
568
+ 'h5' => array(),
569
+ 'h6' => array(),
570
+ 'img' => array( 'src' => array(), 'class' => array(), 'alt' => array() ),
571
  // 'table' => array(),
572
  // 'td' => array(),
573
  // 'tr' => array(),
574
  // 'th' => array(),
575
  // 'thead' => array(),
576
  // 'tbody' => array(),
577
+ );
578
+
579
+ $plugins_section_titles = array(
580
+ 'description' => fs_text_x_inline( 'Description', 'Plugin installer section title', 'description', $api->slug ),
581
+ 'installation' => fs_text_x_inline( 'Installation', 'Plugin installer section title', 'installation', $api->slug ),
582
+ 'faq' => fs_text_x_inline( 'FAQ', 'Plugin installer section title', 'faq', $api->slug ),
583
+ 'screenshots' => fs_text_inline( 'Screenshots', 'screenshots', $api->slug ),
584
+ 'changelog' => fs_text_x_inline( 'Changelog', 'Plugin installer section title', 'changelog', $api->slug ),
585
+ 'reviews' => fs_text_x_inline( 'Reviews', 'Plugin installer section title', 'reviews', $api->slug ),
586
+ 'other_notes' => fs_text_x_inline( 'Other Notes', 'Plugin installer section title', 'other-notes', $api->slug ),
587
+ );
588
+
589
+ // Sanitize HTML
590
  // foreach ( (array) $api->sections as $section_name => $content ) {
591
  // $api->sections[$section_name] = wp_kses( $content, $plugins_allowedtags );
592
  // }
593
 
594
+ foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) {
595
+ if ( isset( $api->$key ) ) {
596
+ $api->$key = wp_kses( $api->$key, $plugins_allowedtags );
597
+ }
598
+ }
599
 
600
+ // Add after $api->slug is ready.
601
+ $plugins_section_titles['features'] = fs_text_x_inline( 'Features & Pricing', 'Plugin installer section title', 'features-and-pricing', $api->slug );
602
 
603
+ $_tab = esc_attr( $tab );
604
 
605
+ $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English.
606
+ if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) {
607
+ $section_titles = array_keys( (array) $api->sections );
608
+ $section = array_shift( $section_titles );
609
+ }
610
 
611
+ iframe_header( fs_text_inline( 'Plugin Install', 'plugin-install', $api->slug ) );
612
 
613
+ $_with_banner = '';
614
 
615
  // var_dump($api->banners);
616
+ if ( ! empty( $api->banners ) && ( ! empty( $api->banners['low'] ) || ! empty( $api->banners['high'] ) ) ) {
617
+ $_with_banner = 'with-banner';
618
+ $low = empty( $api->banners['low'] ) ? $api->banners['high'] : $api->banners['low'];
619
+ $high = empty( $api->banners['high'] ) ? $api->banners['low'] : $api->banners['high'];
620
+ ?>
621
+ <style type="text/css">
622
+ #plugin-information-title.with-banner
623
+ {
624
+ background-image: url( <?php echo esc_url( $low ); ?> );
625
+ }
626
+
627
+ @media only screen and ( -webkit-min-device-pixel-ratio: 1.5 )
628
+ {
629
+ #plugin-information-title.with-banner
630
+ {
631
+ background-image: url( <?php echo esc_url( $high ); ?> );
632
+ }
633
+ }
634
+ </style>
635
+ <?php
636
+ }
637
+
638
+ echo '<div id="plugin-information-scrollable">';
639
+ echo "<div id='{$_tab}-title' class='{$_with_banner}'><div class='vignette'></div><h2>{$api->name}</h2></div>";
640
+ echo "<div id='{$_tab}-tabs' class='{$_with_banner}'>\n";
641
+
642
+ foreach ( (array) $api->sections as $section_name => $content ) {
643
+ if ( 'reviews' === $section_name && ( empty( $api->ratings ) || 0 === array_sum( (array) $api->ratings ) ) ) {
644
+ continue;
645
+ }
646
+
647
+ if ( isset( $plugins_section_titles[ $section_name ] ) ) {
648
+ $title = $plugins_section_titles[ $section_name ];
649
+ } else {
650
+ $title = ucwords( str_replace( '_', ' ', $section_name ) );
651
+ }
652
+
653
+ $class = ( $section_name === $section ) ? ' class="current"' : '';
654
+ $href = add_query_arg( array( 'tab' => $tab, 'section' => $section_name ) );
655
+ $href = esc_url( $href );
656
+ $san_section = esc_attr( $section_name );
657
+ echo "\t<a name='$san_section' href='$href' $class>$title</a>\n";
658
+ }
659
+
660
+ echo "</div>\n";
661
+
662
+ ?>
663
+ <div id="<?php echo $_tab; ?>-content" class='<?php echo $_with_banner; ?>'>
664
+ <div class="fyi">
665
+ <?php if ( $api->is_paid ) : ?>
666
+ <?php if ( isset( $api->plans ) ) : ?>
667
+ <div class="plugin-information-pricing">
668
+ <?php foreach ( $api->plans as $plan ) : ?>
669
+ <?php
670
+ if ( empty( $plan->pricing ) ) {
671
+ continue;
672
+ }
673
+
674
+ /**
675
+ * @var FS_Plugin_Plan $plan
676
+ */
677
+ ?>
678
+ <?php $first_pricing = $plan->pricing[0] ?>
679
+ <?php $is_multi_cycle = $first_pricing->is_multi_cycle() ?>
680
+ <div class="fs-plan<?php if ( ! $is_multi_cycle ) {
681
+ echo ' fs-single-cycle';
682
+ } ?>" data-plan-id="<?php echo $plan->id ?>">
683
+ <h3 data-plan="<?php echo $plan->id ?>"><?php echo esc_html( sprintf( fs_text_x_inline( '%s Plan', 'e.g. Professional Plan', 'x-plan', $api->slug ), $plan->title ) ) ?></h3>
684
+ <?php $has_annual = $first_pricing->has_annual() ?>
685
+ <?php $has_monthly = $first_pricing->has_monthly() ?>
686
+ <div class="nav-tab-wrapper">
687
+ <?php $billing_cycles = array( 'monthly', 'annual', 'lifetime' ) ?>
688
+ <?php $i = 0;
689
+ foreach ( $billing_cycles as $cycle ) : ?>
690
+ <?php $prop = "{$cycle}_price";
691
+ if ( isset( $first_pricing->{$prop} ) ) : ?>
692
+ <?php $is_featured = ( 'annual' === $cycle && $is_multi_cycle ) ?>
693
+ <?php
694
+ $prices = array();
695
+ foreach ( $plan->pricing as $pricing ) {
696
+ if ( isset( $pricing->{$prop} ) ) {
697
+ $prices[] = array(
698
+ 'id' => $pricing->id,
699
+ 'licenses' => $pricing->licenses,
700
+ 'price' => $pricing->{$prop}
701
+ );
702
+ }
703
+ }
704
+ ?>
705
+ <a class="nav-tab" data-billing-cycle="<?php echo $cycle ?>"
706
+ data-pricing="<?php echo esc_attr( json_encode( $prices ) ) ?>">
707
+ <?php if ( $is_featured ) : ?>
708
+ <label>
709
+ &#9733; <?php fs_esc_html_echo_x_inline( 'Best', 'e.g. the best product', 'best', $api->slug ) ?>
710
+ &#9733;</label>
711
+ <?php endif ?>
712
+ <?php
713
+ switch ( $cycle ) {
714
+ case 'monthly':
715
+ fs_esc_html_echo_x_inline( 'Monthly', 'as every month', 'monthly', $api->slug );
716
+ break;
717
+ case 'annual':
718
+ fs_esc_html_echo_x_inline( 'Annual', 'as once a year', 'annual', $api->slug );
719
+ break;
720
+ case 'lifetime':
721
+ fs_esc_html_echo_inline( 'Lifetime', 'lifetime', $api->slug );
722
+ break;
723
+ }
724
+ ?>
725
+ </a>
726
+ <?php endif ?>
727
+ <?php $i ++; endforeach ?>
728
+ <?php wp_enqueue_script( 'jquery' ) ?>
729
+ <script type="text/javascript">
730
+ (function ($, undef) {
731
+ var
732
+ _formatBillingFrequency = function (cycle) {
733
+ switch (cycle) {
734
+ case 'monthly':
735
+ return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug ), fs_text_x_inline( 'Monthly', 'as every month', 'monthly', $api->slug ) ) ?>';
736
+ case 'annual':
737
+ return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug ), fs_text_x_inline( 'Annually', 'as once a year', 'annually', $api->slug ) ) ?>';
738
+ case 'lifetime':
739
+ return '<?php printf( fs_text_x_inline( 'Billed %s', 'e.g. billed monthly', 'billed-x', $api->slug ), fs_text_x_inline( 'Once', 'as once a year', 'once', $api->slug ) ) ?>';
740
+ }
741
+ },
742
+ _formatLicensesTitle = function (pricing) {
743
+ switch (pricing.licenses) {
744
+ case 1:
745
+ return '<?php fs_esc_attr_echo_inline( 'Single Site License', 'license-single-site', $api->slug ) ?>';
746
+ case null:
747
+ return '<?php fs_esc_attr_echo_inline( 'Unlimited Licenses', 'license-unlimited', $api->slug ) ?>';
748
+ default:
749
+ return '<?php fs_esc_attr_echo_inline( 'Up to %s Sites', 'license-x-sites', $api->slug ) ?>'.replace('%s', pricing.licenses);
750
+ }
751
+ },
752
+ _formatPrice = function (pricing, cycle, multipleLicenses) {
753
+ if (undef === multipleLicenses)
754
+ multipleLicenses = true;
755
+
756
+ var priceCycle;
757
+ switch (cycle) {
758
+ case 'monthly':
759
+ priceCycle = ' / <?php fs_echo_x_inline( 'mo', 'as monthly period', 'mo', $api->slug ) ?>';
760
+ break;
761
+ case 'lifetime':
762
+ priceCycle = '';
763
+ break;
764
+ case 'annual':
765
+ default:
766
+ priceCycle = ' / <?php fs_echo_x_inline( 'year', 'as annual period', 'year', $api->slug ) ?>';
767
+ break;
768
+ }
769
+
770
+ if (!multipleLicenses && 1 == pricing.licenses) {
771
+ return '$' + pricing.price + priceCycle;
772
+ }
773
+
774
+ return _formatLicensesTitle(pricing) + ' - <var class="fs-price">$' + pricing.price + priceCycle + '</var>';
775
+ },
776
+ _checkoutUrl = function (plan, pricing, cycle) {
777
+ return '<?php echo esc_url_raw( remove_query_arg( 'billing_cycle', add_query_arg( array( 'plugin_id' => $plan->plugin_id ), $api->checkout_link ) ) ) ?>' +
778
+ '&plan_id=' + plan +
779
+ '&pricing_id=' + pricing +
780
+ '&billing_cycle=' + cycle<?php if ( $plan->has_trial() ) {
781
+ echo " + '&trial=true'";
782
+ }?>;
783
+ },
784
+ _updateCtaUrl = function (plan, pricing, cycle) {
785
+ $('.plugin-information-pricing .button, #plugin-information-footer .button.fs-checkout-button').attr('href', _checkoutUrl(plan, pricing, cycle));
786
+ };
787
+
788
+ $(document).ready(function () {
789
+ var $plan = $('.plugin-information-pricing .fs-plan[data-plan-id=<?php echo $plan->id ?>]');
790
+ $plan.find('input[type=radio]').live('click', function () {
791
+ _updateCtaUrl(
792
+ $plan.attr('data-plan-id'),
793
+ $(this).val(),
794
+ $plan.find('.nav-tab-active').attr('data-billing-cycle')
795
+ );
796
+
797
+ $plan.find('.fs-trial-terms .fs-price').html(
798
+ $(this).parents('label').find('.fs-price').html()
799
+ );
800
+ });
801
+
802
+ $plan.find('.nav-tab').click(function () {
803
+ if ($(this).hasClass('nav-tab-active'))
804
+ return;
805
+
806
+ var $this = $(this),
807
+ billingCycle = $this.attr('data-billing-cycle'),
808
+ pricing = JSON.parse($this.attr('data-pricing')),
809
+ $pricesList = $this.parents('.fs-plan').find('.fs-pricing-body .fs-licenses'),
810
+ html = '';
811
+
812
+ // Un-select previously selected tab.
813
+ $plan.find('.nav-tab').removeClass('nav-tab-active');
814
+
815
+ // Select current tab.
816
+ $this.addClass('nav-tab-active');
817
+
818
+ // Render licenses prices.
819
+ if (1 == pricing.length) {
820
+ html = '<li><label><?php echo fs_esc_attr_x_inline( 'Price', 'noun', 'price', $api->slug ) ?>: ' + _formatPrice(pricing[0], billingCycle, false) + '</label></li>';
821
+ } else {
822
+ for (var i = 0; i < pricing.length; i++) {
823
+ html += '<li><label><input name="pricing-<?php echo $plan->id ?>" type="radio" value="' + pricing[i].id + '">' + _formatPrice(pricing[i], billingCycle) + '</label></li>';
824
+ }
825
+ }
826
+ $pricesList.html(html);
827
+
828
+ if (1 < pricing.length) {
829
+ // Select first license option.
830
+ $pricesList.find('li:first input').click();
831
+ }
832
+ else {
833
+ _updateCtaUrl(
834
+ $plan.attr('data-plan-id'),
835
+ pricing[0].id,
836
+ billingCycle
837
+ );
838
+ }
839
+
840
+ // Update billing frequency.
841
+ $plan.find('.fs-billing-frequency').html(_formatBillingFrequency(billingCycle));
842
+
843
+ if ('annual' === billingCycle) {
844
+ $plan.find('.fs-annual-discount').show();
845
+ } else {
846
+ $plan.find('.fs-annual-discount').hide();
847
+ }
848
+ });
849
+
850
+ <?php if ( $has_annual ) : ?>
851
+ // Select annual by default.
852
+ $plan.find('.nav-tab[data-billing-cycle=annual]').click();
853
+ <?php else : ?>
854
+ // Select first tab.
855
+ $plan.find('.nav-tab:first').click();
856
+ <?php endif ?>
857
+ });
858
+ }(jQuery));
859
+ </script>
860
+ </div>
861
+ <div class="fs-pricing-body">
862
+ <span class="fs-billing-frequency"></span>
863
+ <?php $annual_discount = ( $has_annual && $has_monthly ) ? $plan->pricing[0]->annual_discount_percentage() : 0 ?>
864
+ <?php if ( $annual_discount > 0 ) : ?>
865
+ <span
866
+ class="fs-annual-discount"><?php printf(
867
+ /* translators: %s: Discount (e.g. discount of $5 or 10%) */
868
+ fs_esc_html_inline( 'Save %s', 'save-x', $api->slug ), $annual_discount . '%' ) ?></span>
869
+ <?php endif ?>
870
+ <ul class="fs-licenses">
871
+ </ul>
872
+ <?php echo $this->get_checkout_cta( $api, $plan, false ) ?>
873
+ <div style="clear:both"></div>
874
+ <?php if ( $plan->has_trial() ) : ?>
875
+ <?php $trial_period = $this->get_trial_period( $plan ) ?>
876
+ <ul class="fs-trial-terms">
877
+ <li>
878
+ <i class="dashicons dashicons-yes"></i><?php echo esc_html( sprintf( fs_text_inline( 'No commitment for %s - cancel anytime', 'no-commitment-x', $api->slug ), $trial_period ) ) ?>
879
+ </li>
880
+ <li>
881
+ <i class="dashicons dashicons-yes"></i><?php printf( esc_html( fs_text_inline( 'After your free %s, pay as little as %s', 'after-x-pay-as-little-y', $api->slug ) ), $trial_period, '<var class="fs-price">' . $this->get_price_tag( $plan, $plan->pricing[0] ) . '</var>' ) ?>
882
+ </li>
883
+ </ul>
884
+ <?php endif ?>
885
+ </div>
886
+ </div>
887
+ </div>
888
+ <?php endforeach ?>
889
+ <?php endif ?>
890
+ <?php endif ?>
891
+ <div>
892
+ <h3><?php fs_echo_inline( 'Details', 'details', $api->slug ) ?></h3>
893
+ <ul>
894
+ <?php if ( ! empty( $api->version ) ) { ?>
895
+ <li>
896
+ <strong><?php fs_esc_html_echo_x_inline( 'Version', 'product version', 'version', $api->slug ); ?>
897
+ :</strong> <?php echo $api->version; ?></li>
898
+ <?php
899
+ }
900
+ if ( ! empty( $api->author ) ) {
901
+ ?>
902
+ <li>
903
+ <strong><?php fs_echo_x_inline( 'Author', 'as the plugin author', 'author', $api->slug ); ?>
904
+ :</strong> <?php echo links_add_target( $api->author, '_blank' ); ?>
905
+ </li>
906
+ <?php
907
+ }
908
+ if ( ! empty( $api->last_updated ) ) {
909
+ ?>
910
+ <li><strong><?php fs_echo_inline( 'Last Updated', 'last-updated', $api->slug ); ?>
911
+ :</strong> <span
912
+ title="<?php echo $api->last_updated; ?>">
913
  <?php echo esc_html( sprintf(
914
+ /* translators: %s: time period (e.g. "2 hours" ago) */
915
+ fs_text_x_inline( '%s ago', 'x-ago', $api->slug ),
916
+ human_time_diff( strtotime( $api->last_updated ) )
917
+ ) ) ?>
918
  </span></li>
919
+ <?php
920
+ }
921
+ if ( ! empty( $api->requires ) ) {
922
+ ?>
923
+ <li>
924
+ <strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?>
925
+ :</strong> <?php echo esc_html( sprintf( fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires ) ) ?>
926
+ </li>
927
+ <?php
928
+ }
929
+ if ( ! empty( $api->tested ) ) {
930
+ ?>
931
+ <li>
932
+ <strong><?php fs_esc_html_echo_inline( 'Compatible up to', 'compatible-up-to', $api->slug ); ?>
933
+ :</strong> <?php echo $api->tested; ?>
934
+ </li>
935
+ <?php
936
+ }
937
+ if ( ! empty( $api->downloaded ) ) {
938
+ ?>
939
+ <li>
940
+ <strong><?php fs_esc_html_echo_inline( 'Downloaded', 'downloaded', $api->slug ) ?>
941
+ :</strong> <?php echo esc_html( sprintf(
942
+ ( ( 1 == $api->downloaded ) ?
943
+ /* translators: %s: 1 or One (Number of times downloaded) */
944
+ fs_text_inline( '%s time', 'x-time', $api->slug ) :
945
+ /* translators: %s: Number of times downloaded */
946
+ fs_text_inline( '%s times', 'x-times', $api->slug )
947
+ ),
948
+ number_format_i18n( $api->downloaded )
949
+ ) ); ?>
950
+ </li>
951
+ <?php
952
+ }
953
+ if ( ! empty( $api->slug ) && empty( $api->is_wp_org_compliant ) ) {
954
+ ?>
955
+ <li><a target="_blank"
956
+ href="https://wordpress.org/plugins/<?php echo $api->slug; ?>/"><?php fs_esc_html_echo_inline( 'WordPress.org Plugin Page', 'wp-org-plugin-page', $api->slug ) ?>
957
+ &#187;</a>
958
+ </li>
959
+ <?php
960
+ }
961
+ if ( ! empty( $api->homepage ) ) {
962
+ ?>
963
+ <li><a target="_blank"
964
+ href="<?php echo esc_url( $api->homepage ); ?>"><?php fs_esc_html_echo_inline( 'Plugin Homepage', 'plugin-homepage', $api->slug ) ?>
965
+ &#187;</a>
966
+ </li>
967
+ <?php
968
+ }
969
+ if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) {
970
+ ?>
971
+ <li><a target="_blank"
972
+ href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_esc_html_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?>
973
+ &#187;</a>
974
+ </li>
975
+ <?php } ?>
976
+ </ul>
977
+ </div>
978
+ <?php if ( ! empty( $api->rating ) ) { ?>
979
+ <h3><?php fs_echo_inline( 'Average Rating', 'average-rating', $api->slug ); ?></h3>
980
+ <?php wp_star_rating( array(
981
+ 'rating' => $api->rating,
982
+ 'type' => 'percent',
983
+ 'number' => $api->num_ratings
984
+ ) ); ?>
985
+ <small>(<?php echo esc_html( sprintf(
986
+ fs_text_inline( 'based on %s', 'based-on-x', $api->slug ),
987
+ sprintf(
988
+ ( ( 1 == $api->num_ratings ) ?
989
+ /* translators: %s: 1 or One */
990
+ fs_text_inline( '%s rating', 'x-rating', $api->slug ) :
991
+ /* translators: %s: Number larger than 1 */
992
+ fs_text_inline( '%s ratings', 'x-ratings', $api->slug )
993
+ ),
994
+ number_format_i18n( $api->num_ratings )
995
+ ) ) ) ?>)
996
+ </small>
997
+ <?php
998
+ }
999
+
1000
+ if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) {
1001
+ foreach ( $api->ratings as $key => $ratecount ) {
1002
+ // Avoid div-by-zero.
1003
+ $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0;
1004
+ $stars_label = sprintf(
1005
+ ( ( 1 == $key ) ?
1006
+ /* translators: %s: 1 or One */
1007
+ fs_text_inline( '%s star', 'x-star', $api->slug ) :
1008
+ /* translators: %s: Number larger than 1 */
1009
+ fs_text_inline( '%s stars', 'x-stars', $api->slug )
1010
+ ),
1011
+ number_format_i18n( $key )
1012
+ );
1013
+ ?>
1014
+ <div class="counter-container">
1015
  <span class="counter-label"><a
1016
+ href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
1017
+ target="_blank"
1018
+ title="<?php echo esc_attr( sprintf(
1019
+ /* translators: %s: # of stars (e.g. 5 stars) */
1020
+ fs_text_inline( 'Click to see reviews that provided a rating of %s', 'click-to-reviews', $api->slug ),
1021
+ $stars_label
1022
+ ) ) ?>"><?php echo $stars_label ?></a></span>
1023
+ <span class="counter-back">
1024
  <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
1025
  </span>
1026
+ <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
1027
+ </div>
1028
+ <?php
1029
+ }
1030
+ }
1031
+ if ( ! empty( $api->contributors ) ) {
1032
+ ?>
1033
+ <h3><?php fs_echo_inline( 'Contributors', 'contributors', $api->slug ); ?></h3>
1034
+ <ul class="contributors">
1035
+ <?php
1036
+ foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) {
1037
+ if ( empty( $contrib_username ) && empty( $contrib_profile ) ) {
1038
+ continue;
1039
+ }
1040
+ if ( empty( $contrib_username ) ) {
1041
+ $contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile );
1042
+ }
1043
+ $contrib_username = sanitize_user( $contrib_username );
1044
+ if ( empty( $contrib_profile ) ) {
1045
+ echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</li>";
1046
+ } else {
1047
+ echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
1048
+ }
1049
+ }
1050
+ ?>
1051
+ </ul>
1052
+ <?php if ( ! empty( $api->donate_link ) ) { ?>
1053
+ <a target="_blank"
1054
+ href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?>
1055
+ &#187;</a>
1056
+ <?php } ?>
1057
+ <?php } ?>
1058
+ </div>
1059
+ <div id="section-holder" class="wrap">
1060
+ <?php
1061
+ if ( ! empty( $api->tested ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->tested ) ), $api->tested, '>' ) ) {
1062
+ echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '</p></div>';
1063
+ } else if ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) {
1064
+ echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '</p></div>';
1065
+ }
1066
+
1067
+ foreach ( (array) $api->sections as $section_name => $content ) {
1068
+ $content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' );
1069
+ $content = links_add_target( $content, '_blank' );
1070
+
1071
+ $san_section = esc_attr( $section_name );
1072
+
1073
+ $display = ( $section_name === $section ) ? 'block' : 'none';
1074
+
1075
+ if ( 'description' === $section_name &&
1076
+ ( ( $api->is_wp_org_compliant && $api->wp_org_missing ) ||
1077
+ ( ! $api->is_wp_org_compliant && $api->fs_missing ) )
1078
+ ) {
1079
+ $missing_notice = array(
1080
+ 'type' => 'error',
1081
+ 'id' => md5( microtime() ),
1082
+ 'message' => $api->is_paid ?
1083
+ fs_text_inline( 'Paid add-on must be deployed to Freemius.', 'paid-addon-not-deployed', $api->slug ) :
1084
+ fs_text_inline( 'Add-on must be deployed to WordPress.org or Freemius.', 'free-addon-not-deployed', $api->slug ),
1085
+ );
1086
+ fs_require_template( 'admin-notice.php', $missing_notice );
1087
+ }
1088
+ echo "\t<div id='section-{$san_section}' class='section' style='display: {$display};'>\n";
1089
+ echo $content;
1090
+ echo "\t</div>\n";
1091
+ }
1092
+ echo "</div>\n";
1093
+ echo "</div>\n";
1094
+ echo "</div>\n"; // #plugin-information-scrollable
1095
+ echo "<div id='$tab-footer'>\n";
1096
+
1097
+ if ( ! empty( $api->checkout_link ) ) {
1098
+ echo $this->get_checkout_cta( $api );
1099
+ }
1100
+
1101
+ if ( ! empty( $api->download_link ) ) {
1102
+ echo $this->get_download_cta( $api, empty( $api->checkout_link ) );
1103
+ }
1104
+
1105
+ echo "</div>\n";
1106
+
1107
+ iframe_footer();
1108
+ exit;
1109
+ }
1110
+ }
sdk/freemius/includes/sdk/FreemiusWordPress.php CHANGED
@@ -390,9 +390,11 @@
390
 
391
  $resource = explode( '?', $pCanonizedPath );
392
 
393
- // Disable the 'Expect: 100-continue' behaviour. This causes cURL to wait
394
- // for 2 seconds if the server does not support this header.
395
- $pWPRemoteArgs['headers']['Expect'] = '';
 
 
396
 
397
  if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
398
  $pWPRemoteArgs['sslverify'] = false;
390
 
391
  $resource = explode( '?', $pCanonizedPath );
392
 
393
+ if ( FS_SDK__HAS_CURL ) {
394
+ // Disable the 'Expect: 100-continue' behaviour. This causes cURL to wait
395
+ // for 2 seconds if the server does not support this header.
396
+ $pWPRemoteArgs['headers']['Expect'] = '';
397
+ }
398
 
399
  if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
400
  $pWPRemoteArgs['sslverify'] = false;
sdk/freemius/languages/freemius.pot CHANGED
@@ -140,7 +140,7 @@ msgstr ""
140
  msgid "No - just deactivate"
141
  msgstr ""
142
 
143
- #: includes/class-freemius.php:3508, includes/class-freemius.php:3986, includes/class-freemius.php:5056, includes/class-freemius.php:10786, includes/class-freemius.php:13974, includes/class-freemius.php:14026, includes/class-freemius.php:14087, includes/class-freemius.php:16213, includes/class-freemius.php:16223, includes/class-freemius.php:16773, includes/class-freemius.php:16791, includes/class-freemius.php:16889, includes/class-freemius.php:17625, templates/add-ons.php:43
144
  msgctxt "exclamation"
145
  msgid "Oops"
146
  msgstr ""
@@ -149,509 +149,509 @@ msgstr ""
149
  msgid "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."
150
  msgstr ""
151
 
152
- #: includes/class-freemius.php:3983
153
  msgctxt "addonX cannot run without pluginY"
154
  msgid "%s cannot run without %s."
155
  msgstr ""
156
 
157
- #: includes/class-freemius.php:3984
158
  msgctxt "addonX cannot run..."
159
  msgid "%s cannot run without the plugin."
160
  msgstr ""
161
 
162
- #: includes/class-freemius.php:4105, includes/class-freemius.php:4130, includes/class-freemius.php:16862
163
  msgid "Unexpected API error. Please contact the %s's author with the following error."
164
  msgstr ""
165
 
166
- #: includes/class-freemius.php:4744
167
  msgid "Premium %s version was successfully activated."
168
  msgstr ""
169
 
170
- #: includes/class-freemius.php:4756, includes/class-freemius.php:6587
171
  msgctxt "Used to express elation, enthusiasm, or triumph (especially in electronic communication)."
172
  msgid "W00t"
173
  msgstr ""
174
 
175
- #: includes/class-freemius.php:4771
176
  msgid "You have a %s license."
177
  msgstr ""
178
 
179
- #: includes/class-freemius.php:4775, includes/class-freemius.php:13415, includes/class-freemius.php:13426, includes/class-freemius.php:16141, includes/class-freemius.php:16441, includes/class-freemius.php:16503, includes/class-freemius.php:16650
180
  msgctxt "interjection expressing joy or exuberance"
181
  msgid "Yee-haw"
182
  msgstr ""
183
 
184
- #: includes/class-freemius.php:5039
185
  msgid "%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you'll have to purchase a license."
186
  msgstr ""
187
 
188
- #: includes/class-freemius.php:5043
189
  msgid "%s is a premium only add-on. You have to purchase a license first before activating the plugin."
190
  msgstr ""
191
 
192
- #: includes/class-freemius.php:5052, templates/account.php:780, templates/add-ons.php:99
193
  msgid "More information about %s"
194
  msgstr ""
195
 
196
- #: includes/class-freemius.php:5053
197
  msgid "Purchase License"
198
  msgstr ""
199
 
200
- #: includes/class-freemius.php:5964, templates/connect.php:153
201
  msgid "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 %s."
202
  msgstr ""
203
 
204
- #: includes/class-freemius.php:5968
205
  msgid "start the trial"
206
  msgstr ""
207
 
208
- #: includes/class-freemius.php:5969, templates/connect.php:157
209
  msgid "complete the install"
210
  msgstr ""
211
 
212
- #: includes/class-freemius.php:6070
213
  msgid "You are just one step away - %s"
214
  msgstr ""
215
 
216
- #: includes/class-freemius.php:6073
217
  msgctxt "%s - plugin name. As complete \"PluginX\" activation now"
218
  msgid "Complete \"%s\" Activation Now"
219
  msgstr ""
220
 
221
- #: includes/class-freemius.php:6152
222
  msgid "We made a few tweaks to the %s, %s"
223
  msgstr ""
224
 
225
- #: includes/class-freemius.php:6156
226
  msgid "Opt in to make \"%s\" Better!"
227
  msgstr ""
228
 
229
- #: includes/class-freemius.php:6586
230
  msgid "The upgrade of %s was successfully completed."
231
  msgstr ""
232
 
233
- #: includes/class-freemius.php:8301, includes/class-fs-plugin-updater.php:505, includes/class-fs-plugin-updater.php:657, includes/class-fs-plugin-updater.php:663, templates/auto-installation.php:32
234
  msgid "Add-On"
235
  msgstr ""
236
 
237
- #: includes/class-freemius.php:8303, templates/debug.php:336, templates/debug.php:497
238
  msgid "Plugin"
239
  msgstr ""
240
 
241
- #: includes/class-freemius.php:8304, templates/debug.php:336, templates/debug.php:497, templates/forms/deactivation/form.php:64
242
  msgid "Theme"
243
  msgstr ""
244
 
245
- #: includes/class-freemius.php:10653
246
  msgid "invalid_site_details_collection"
247
  msgstr ""
248
 
249
- #: includes/class-freemius.php:10773
250
  msgid "We couldn't find your email address in the system, are you sure it's the right address?"
251
  msgstr ""
252
 
253
- #: includes/class-freemius.php:10775
254
  msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
255
  msgstr ""
256
 
257
- #: includes/class-freemius.php:11001
258
  msgid "Account is pending activation."
259
  msgstr ""
260
 
261
- #: includes/class-freemius.php:13397
262
  msgid "%s activation was successfully completed."
263
  msgstr ""
264
 
265
- #: includes/class-freemius.php:13411
266
  msgid "Your account was successfully activated with the %s plan."
267
  msgstr ""
268
 
269
- #: includes/class-freemius.php:13422, includes/class-freemius.php:16499
270
  msgid "Your trial has been successfully started."
271
  msgstr ""
272
 
273
- #: includes/class-freemius.php:13972, includes/class-freemius.php:14024, includes/class-freemius.php:14085
274
  msgid "Couldn't activate %s."
275
  msgstr ""
276
 
277
- #: includes/class-freemius.php:13973, includes/class-freemius.php:14025, includes/class-freemius.php:14086
278
  msgid "Please contact us with the following message:"
279
  msgstr ""
280
 
281
- #: includes/class-freemius.php:14433, includes/class-freemius.php:18689
282
  msgid "Upgrade"
283
  msgstr ""
284
 
285
- #: includes/class-freemius.php:14439
286
  msgid "Start Trial"
287
  msgstr ""
288
 
289
- #: includes/class-freemius.php:14441
290
  msgid "Pricing"
291
  msgstr ""
292
 
293
- #: includes/class-freemius.php:14501, includes/class-freemius.php:14503
294
  msgid "Affiliation"
295
  msgstr ""
296
 
297
- #: includes/class-freemius.php:14523, includes/class-freemius.php:14525, templates/account.php:145, templates/debug.php:301
298
  msgid "Account"
299
  msgstr ""
300
 
301
- #: includes/class-freemius.php:14536, includes/class-freemius.php:14538, includes/customizer/class-fs-customizer-support-section.php:60
302
  msgid "Contact Us"
303
  msgstr ""
304
 
305
- #: includes/class-freemius.php:14548, includes/class-freemius.php:14550, includes/class-freemius.php:18699, templates/account.php:96
306
  msgid "Add-Ons"
307
  msgstr ""
308
 
309
- #: includes/class-freemius.php:14581, templates/pricing.php:97
310
  msgctxt "noun"
311
  msgid "Pricing"
312
  msgstr ""
313
 
314
- #: includes/class-freemius.php:14774, includes/customizer/class-fs-customizer-support-section.php:67
315
  msgid "Support Forum"
316
  msgstr ""
317
 
318
- #: includes/class-freemius.php:15559
319
  msgid "Your email has been successfully verified - you are AWESOME!"
320
  msgstr ""
321
 
322
- #: includes/class-freemius.php:15560
323
  msgctxt "a positive response"
324
  msgid "Right on"
325
  msgstr ""
326
 
327
- #: includes/class-freemius.php:16132
328
  msgid "Your %s Add-on plan was successfully upgraded."
329
  msgstr ""
330
 
331
- #: includes/class-freemius.php:16134
332
  msgid "%s Add-on was successfully purchased."
333
  msgstr ""
334
 
335
- #: includes/class-freemius.php:16137
336
  msgid "Download the latest version"
337
  msgstr ""
338
 
339
- #: includes/class-freemius.php:16209
340
  msgctxt "%1s - plugin title, %2s - API domain"
341
  msgid "Your server is blocking the access to Freemius' API, which is crucial for %1s synchronization. Please contact your host to whitelist %2s"
342
  msgstr ""
343
 
344
- #: includes/class-freemius.php:16212, includes/class-freemius.php:16621, includes/class-freemius.php:16686
345
  msgid "Error received from the server:"
346
  msgstr ""
347
 
348
- #: includes/class-freemius.php:16222
349
  msgid "It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again."
350
  msgstr ""
351
 
352
- #: includes/class-freemius.php:16404, includes/class-freemius.php:16626, includes/class-freemius.php:16669
353
  msgctxt "something somebody says when they are thinking about what you have just said."
354
  msgid "Hmm"
355
  msgstr ""
356
 
357
- #: includes/class-freemius.php:16417
358
  msgid "It looks like you are still on the %s plan. If you did upgrade or change your plan, it's probably an issue on our side - sorry."
359
  msgstr ""
360
 
361
- #: includes/class-freemius.php:16418, templates/account.php:98, templates/add-ons.php:130
362
  msgctxt "trial period"
363
  msgid "Trial"
364
  msgstr ""
365
 
366
- #: includes/class-freemius.php:16423
367
  msgid "I have upgraded my account but when I try to Sync the License, the plan remains %s."
368
  msgstr ""
369
 
370
- #: includes/class-freemius.php:16427, includes/class-freemius.php:16481
371
  msgid "Please contact us here"
372
  msgstr ""
373
 
374
- #: includes/class-freemius.php:16437
375
  msgid "Your plan was successfully upgraded."
376
  msgstr ""
377
 
378
- #: includes/class-freemius.php:16454
379
  msgid "Your plan was successfully changed to %s."
380
  msgstr ""
381
 
382
- #: includes/class-freemius.php:16469
383
  msgid "Your license has expired. You can still continue using the free %s forever."
384
  msgstr ""
385
 
386
- #: includes/class-freemius.php:16477
387
  msgid "Your license has been cancelled. If you think it's a mistake, please contact support."
388
  msgstr ""
389
 
390
- #: includes/class-freemius.php:16490
391
  msgid "Your license has expired. You can still continue using all the %s features, but you'll need to renew your license to continue getting updates and support."
392
  msgstr ""
393
 
394
- #: includes/class-freemius.php:16512
395
  msgid "Your trial has expired. You can still continue using all our free features."
396
  msgstr ""
397
 
398
- #: includes/class-freemius.php:16617
399
  msgid "It looks like the license could not be activated."
400
  msgstr ""
401
 
402
- #: includes/class-freemius.php:16647
403
  msgid "Your license was successfully activated."
404
  msgstr ""
405
 
406
- #: includes/class-freemius.php:16673
407
  msgid "It looks like your site currently doesn't have an active license."
408
  msgstr ""
409
 
410
- #: includes/class-freemius.php:16685
411
  msgid "It looks like the license deactivation failed."
412
  msgstr ""
413
 
414
- #: includes/class-freemius.php:16713
415
  msgid "Your license was successfully deactivated, you are back to the %s plan."
416
  msgstr ""
417
 
418
- #: includes/class-freemius.php:16714
419
  msgid "O.K"
420
  msgstr ""
421
 
422
- #: includes/class-freemius.php:16762
423
  msgid "Your plan was successfully downgraded. Your %s plan license will expire in %s."
424
  msgstr ""
425
 
426
- #: includes/class-freemius.php:16772
427
  msgid "Seems like we are having some temporary issue with your plan downgrade. Please try again in few minutes."
428
  msgstr ""
429
 
430
- #: includes/class-freemius.php:16796
431
  msgid "You are already running the %s in a trial mode."
432
  msgstr ""
433
 
434
- #: includes/class-freemius.php:16807
435
  msgid "You already utilized a trial before."
436
  msgstr ""
437
 
438
- #: includes/class-freemius.php:16821
439
  msgid "Plan %s do not exist, therefore, can't start a trial."
440
  msgstr ""
441
 
442
- #: includes/class-freemius.php:16832
443
  msgid "Plan %s does not support a trial period."
444
  msgstr ""
445
 
446
- #: includes/class-freemius.php:16843
447
  msgid "None of the %s's plans supports a trial period."
448
  msgstr ""
449
 
450
- #: includes/class-freemius.php:16893
451
  msgid "It looks like you are not in trial mode anymore so there's nothing to cancel :)"
452
  msgstr ""
453
 
454
- #: includes/class-freemius.php:16944
455
  msgid "Your %s free trial was successfully cancelled."
456
  msgstr ""
457
 
458
- #: includes/class-freemius.php:16949
459
  msgid "Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes."
460
  msgstr ""
461
 
462
- #: includes/class-freemius.php:17233
463
  msgid "Version %s was released."
464
  msgstr ""
465
 
466
- #: includes/class-freemius.php:17233
467
  msgid "Please download %s."
468
  msgstr ""
469
 
470
- #: includes/class-freemius.php:17240
471
  msgid "the latest %s version here"
472
  msgstr ""
473
 
474
- #: includes/class-freemius.php:17245
475
  msgid "New"
476
  msgstr ""
477
 
478
- #: includes/class-freemius.php:17250
479
  msgid "Seems like you got the latest release."
480
  msgstr ""
481
 
482
- #: includes/class-freemius.php:17251
483
  msgid "You are all good!"
484
  msgstr ""
485
 
486
- #: includes/class-freemius.php:17517
487
  msgid "Verification mail was just sent to %s. If you can't find it after 5 min, please check your spam box."
488
  msgstr ""
489
 
490
- #: includes/class-freemius.php:17652
491
  msgid "Site successfully opted in."
492
  msgstr ""
493
 
494
- #: includes/class-freemius.php:17653, includes/class-freemius.php:18430
495
  msgid "Awesome"
496
  msgstr ""
497
 
498
- #: includes/class-freemius.php:17669, templates/forms/optout.php:32
499
  msgid "We appreciate your help in making the %s better by letting us track some usage data."
500
  msgstr ""
501
 
502
- #: includes/class-freemius.php:17670
503
  msgid "Thank you!"
504
  msgstr ""
505
 
506
- #: includes/class-freemius.php:17677
507
  msgid "We will no longer be sending any usage data of %s on %s to %s."
508
  msgstr ""
509
 
510
- #: includes/class-freemius.php:17792
511
  msgid "Please check your mailbox, you should receive an email via %s to confirm the ownership change. From security reasons, you must confirm the change within the next 15 min. If you cannot find the email, please check your spam folder."
512
  msgstr ""
513
 
514
- #: includes/class-freemius.php:17798
515
  msgid "Thanks for confirming the ownership change. An email was just sent to %s for final approval."
516
  msgstr ""
517
 
518
- #: includes/class-freemius.php:17803
519
  msgid "%s is the new owner of the account."
520
  msgstr ""
521
 
522
- #: includes/class-freemius.php:17805
523
  msgctxt "as congratulations"
524
  msgid "Congrats"
525
  msgstr ""
526
 
527
- #: includes/class-freemius.php:17825
528
  msgid "Sorry, we could not complete the email update. Another user with the same email is already registered."
529
  msgstr ""
530
 
531
- #: includes/class-freemius.php:17826
532
  msgid "If you would like to give up the ownership of the %s's account to %s click the Change Ownership button."
533
  msgstr ""
534
 
535
- #: includes/class-freemius.php:17833
536
  msgid "Change Ownership"
537
  msgstr ""
538
 
539
- #: includes/class-freemius.php:17841
540
  msgid "Your email was successfully updated. You should receive an email with confirmation instructions in few moments."
541
  msgstr ""
542
 
543
- #: includes/class-freemius.php:17853
544
  msgid "Please provide your full name."
545
  msgstr ""
546
 
547
- #: includes/class-freemius.php:17858
548
  msgid "Your name was successfully updated."
549
  msgstr ""
550
 
551
- #: includes/class-freemius.php:17919
552
  msgid "You have successfully updated your %s."
553
  msgstr ""
554
 
555
- #: includes/class-freemius.php:18059
556
  msgid "Just letting you know that the add-ons information of %s is being pulled from an external server."
557
  msgstr ""
558
 
559
- #: includes/class-freemius.php:18060
560
  msgctxt "advance notice of something that will need attention."
561
  msgid "Heads up"
562
  msgstr ""
563
 
564
- #: includes/class-freemius.php:18470
565
  msgctxt "exclamation"
566
  msgid "Hey"
567
  msgstr ""
568
 
569
- #: includes/class-freemius.php:18470
570
  msgid "How do you like %s so far? Test all our %s premium features with a %d-day free trial."
571
  msgstr ""
572
 
573
- #: includes/class-freemius.php:18478
574
  msgid "No commitment for %s days - cancel anytime!"
575
  msgstr ""
576
 
577
- #: includes/class-freemius.php:18479
578
  msgid "No credit card required"
579
  msgstr ""
580
 
581
- #: includes/class-freemius.php:18486, templates/forms/trial-start.php:53
582
  msgctxt "call to action"
583
  msgid "Start free trial"
584
  msgstr ""
585
 
586
- #: includes/class-freemius.php:18563
587
  msgid "Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!"
588
  msgstr ""
589
 
590
- #: includes/class-freemius.php:18572
591
  msgid "Learn more"
592
  msgstr ""
593
 
594
- #: includes/class-freemius.php:18728, templates/account.php:393, templates/account.php:496, templates/connect.php:161, templates/connect.php:371, templates/forms/license-activation.php:24
595
  msgid "Activate License"
596
  msgstr ""
597
 
598
- #: includes/class-freemius.php:18729, templates/account.php:456, templates/account.php:495, templates/account/partials/site.php:256
599
  msgid "Change License"
600
  msgstr ""
601
 
602
- #: includes/class-freemius.php:18799, templates/account/partials/site.php:161
603
  msgid "Opt Out"
604
  msgstr ""
605
 
606
- #: includes/class-freemius.php:18801, includes/class-freemius.php:18806, templates/account/partials/site.php:43, templates/account/partials/site.php:161
607
  msgid "Opt In"
608
  msgstr ""
609
 
610
- #: includes/class-freemius.php:18998
611
  msgid "Please follow these steps to complete the upgrade"
612
  msgstr ""
613
 
614
- #: includes/class-freemius.php:19002
615
  msgid "Download the latest %s version"
616
  msgstr ""
617
 
618
- #: includes/class-freemius.php:19006
619
  msgid "Upload and activate the downloaded version"
620
  msgstr ""
621
 
622
- #: includes/class-freemius.php:19008
623
  msgid "How to upload and activate?"
624
  msgstr ""
625
 
626
- #: includes/class-freemius.php:19053
627
  msgid "%sClick here%s to choose the sites where you'd like to activate the license on."
628
  msgstr ""
629
 
630
- #: includes/class-freemius.php:19214
631
  msgid "Auto installation only works for opted-in users."
632
  msgstr ""
633
 
634
- #: includes/class-freemius.php:19224, includes/class-freemius.php:19257, includes/class-fs-plugin-updater.php:637, includes/class-fs-plugin-updater.php:651
635
  msgid "Invalid module ID."
636
  msgstr ""
637
 
638
- #: includes/class-freemius.php:19233, includes/class-fs-plugin-updater.php:671
639
  msgid "Premium version already active."
640
  msgstr ""
641
 
642
- #: includes/class-freemius.php:19240
643
  msgid "You do not have a valid license to access the premium version."
644
  msgstr ""
645
 
646
- #: includes/class-freemius.php:19247
647
  msgid "Plugin is a \"Serviceware\" which means it does not have a premium code version."
648
  msgstr ""
649
 
650
- #: includes/class-freemius.php:19265, includes/class-fs-plugin-updater.php:670
651
  msgid "Premium add-on version already installed."
652
  msgstr ""
653
 
654
- #: includes/class-freemius.php:19610
655
  msgid "View paid features"
656
  msgstr ""
657
 
@@ -671,503 +671,503 @@ msgstr ""
671
  msgid "The remote plugin package does not contain a folder with the desired slug and renaming did not work."
672
  msgstr ""
673
 
674
- #: includes/fs-plugin-info-dialog.php:328, templates/account.php:784
675
  msgctxt "verb"
676
  msgid "Purchase"
677
  msgstr ""
678
 
679
- #: includes/fs-plugin-info-dialog.php:331
680
  msgid "Start my free %s"
681
  msgstr ""
682
 
683
- #: includes/fs-plugin-info-dialog.php:355, templates/account.php:80
 
 
 
 
 
 
 
 
 
 
 
 
 
684
  msgctxt "as download latest version"
685
  msgid "Download Latest"
686
  msgstr ""
687
 
688
- #: includes/fs-plugin-info-dialog.php:358, templates/account.php:764, templates/account.php:817, templates/auto-installation.php:111
689
- msgid "Install Now"
690
  msgstr ""
691
 
692
- #: includes/fs-plugin-info-dialog.php:364, templates/account.php:447
693
  msgid "Install Update Now"
694
  msgstr ""
695
 
696
- #: includes/fs-plugin-info-dialog.php:368
 
 
 
 
697
  msgid "Newer Version (%s) Installed"
698
  msgstr ""
699
 
700
- #: includes/fs-plugin-info-dialog.php:371
 
 
 
 
701
  msgid "Latest Version Installed"
702
  msgstr ""
703
 
704
- #: includes/fs-plugin-info-dialog.php:484
705
  msgctxt "Plugin installer section title"
706
  msgid "Description"
707
  msgstr ""
708
 
709
- #: includes/fs-plugin-info-dialog.php:485
710
  msgctxt "Plugin installer section title"
711
  msgid "Installation"
712
  msgstr ""
713
 
714
- #: includes/fs-plugin-info-dialog.php:486
715
  msgctxt "Plugin installer section title"
716
  msgid "FAQ"
717
  msgstr ""
718
 
719
- #: includes/fs-plugin-info-dialog.php:487, templates/plugin-info/description.php:55
720
  msgid "Screenshots"
721
  msgstr ""
722
 
723
- #: includes/fs-plugin-info-dialog.php:488
724
  msgctxt "Plugin installer section title"
725
  msgid "Changelog"
726
  msgstr ""
727
 
728
- #: includes/fs-plugin-info-dialog.php:489
729
  msgctxt "Plugin installer section title"
730
  msgid "Reviews"
731
  msgstr ""
732
 
733
- #: includes/fs-plugin-info-dialog.php:490
734
  msgctxt "Plugin installer section title"
735
  msgid "Other Notes"
736
  msgstr ""
737
 
738
- #: includes/fs-plugin-info-dialog.php:505
739
  msgctxt "Plugin installer section title"
740
  msgid "Features & Pricing"
741
  msgstr ""
742
 
743
- #: includes/fs-plugin-info-dialog.php:515
744
  msgid "Plugin Install"
745
  msgstr ""
746
 
747
- #: includes/fs-plugin-info-dialog.php:587
748
  msgctxt "e.g. Professional Plan"
749
  msgid "%s Plan"
750
  msgstr ""
751
 
752
- #: includes/fs-plugin-info-dialog.php:612
753
  msgctxt "e.g. the best product"
754
  msgid "Best"
755
  msgstr ""
756
 
757
- #: includes/fs-plugin-info-dialog.php:618, includes/fs-plugin-info-dialog.php:638
758
  msgctxt "as every month"
759
  msgid "Monthly"
760
  msgstr ""
761
 
762
- #: includes/fs-plugin-info-dialog.php:621
763
  msgctxt "as once a year"
764
  msgid "Annual"
765
  msgstr ""
766
 
767
- #: includes/fs-plugin-info-dialog.php:624
768
  msgid "Lifetime"
769
  msgstr ""
770
 
771
- #: includes/fs-plugin-info-dialog.php:638, includes/fs-plugin-info-dialog.php:640, includes/fs-plugin-info-dialog.php:642
772
  msgctxt "e.g. billed monthly"
773
  msgid "Billed %s"
774
  msgstr ""
775
 
776
- #: includes/fs-plugin-info-dialog.php:640
777
  msgctxt "as once a year"
778
  msgid "Annually"
779
  msgstr ""
780
 
781
- #: includes/fs-plugin-info-dialog.php:642
782
  msgctxt "as once a year"
783
  msgid "Once"
784
  msgstr ""
785
 
786
- #: includes/fs-plugin-info-dialog.php:648
787
  msgid "Single Site License"
788
  msgstr ""
789
 
790
- #: includes/fs-plugin-info-dialog.php:650
791
  msgid "Unlimited Licenses"
792
  msgstr ""
793
 
794
- #: includes/fs-plugin-info-dialog.php:652
795
  msgid "Up to %s Sites"
796
  msgstr ""
797
 
798
- #: includes/fs-plugin-info-dialog.php:662, templates/plugin-info/features.php:82
799
  msgctxt "as monthly period"
800
  msgid "mo"
801
  msgstr ""
802
 
803
- #: includes/fs-plugin-info-dialog.php:669, templates/plugin-info/features.php:80
804
  msgctxt "as annual period"
805
  msgid "year"
806
  msgstr ""
807
 
808
- #: includes/fs-plugin-info-dialog.php:721
809
  msgctxt "noun"
810
  msgid "Price"
811
  msgstr ""
812
 
813
- #: includes/fs-plugin-info-dialog.php:769
814
  msgid "Save %s"
815
  msgstr ""
816
 
817
- #: includes/fs-plugin-info-dialog.php:779
818
  msgid "No commitment for %s - cancel anytime"
819
  msgstr ""
820
 
821
- #: includes/fs-plugin-info-dialog.php:782
822
  msgid "After your free %s, pay as little as %s"
823
  msgstr ""
824
 
825
- #: includes/fs-plugin-info-dialog.php:793
826
  msgid "Details"
827
  msgstr ""
828
 
829
- #: includes/fs-plugin-info-dialog.php:796, templates/account.php:87, templates/debug.php:191, templates/debug.php:228, templates/debug.php:429
830
  msgctxt "product version"
831
  msgid "Version"
832
  msgstr ""
833
 
834
- #: includes/fs-plugin-info-dialog.php:802
835
  msgctxt "as the plugin author"
836
  msgid "Author"
837
  msgstr ""
838
 
839
- #: includes/fs-plugin-info-dialog.php:808
840
  msgid "Last Updated"
841
  msgstr ""
842
 
843
- #: includes/fs-plugin-info-dialog.php:812
844
  msgctxt "x-ago"
845
  msgid "%s ago"
846
  msgstr ""
847
 
848
- #: includes/fs-plugin-info-dialog.php:821
849
  msgid "Requires WordPress Version"
850
  msgstr ""
851
 
852
- #: includes/fs-plugin-info-dialog.php:821
853
  msgid "%s or higher"
854
  msgstr ""
855
 
856
- #: includes/fs-plugin-info-dialog.php:827
857
  msgid "Compatible up to"
858
  msgstr ""
859
 
860
- #: includes/fs-plugin-info-dialog.php:834
861
  msgid "Downloaded"
862
  msgstr ""
863
 
864
- #: includes/fs-plugin-info-dialog.php:837
865
  msgid "%s time"
866
  msgstr ""
867
 
868
- #: includes/fs-plugin-info-dialog.php:839
869
  msgid "%s times"
870
  msgstr ""
871
 
872
- #: includes/fs-plugin-info-dialog.php:849
873
  msgid "WordPress.org Plugin Page"
874
  msgstr ""
875
 
876
- #: includes/fs-plugin-info-dialog.php:856
877
  msgid "Plugin Homepage"
878
  msgstr ""
879
 
880
- #: includes/fs-plugin-info-dialog.php:863, includes/fs-plugin-info-dialog.php:943
881
  msgid "Donate to this plugin"
882
  msgstr ""
883
 
884
- #: includes/fs-plugin-info-dialog.php:869
885
  msgid "Average Rating"
886
  msgstr ""
887
 
888
- #: includes/fs-plugin-info-dialog.php:876
889
  msgid "based on %s"
890
  msgstr ""
891
 
892
- #: includes/fs-plugin-info-dialog.php:880
893
  msgid "%s rating"
894
  msgstr ""
895
 
896
- #: includes/fs-plugin-info-dialog.php:882
897
  msgid "%s ratings"
898
  msgstr ""
899
 
900
- #: includes/fs-plugin-info-dialog.php:896
901
  msgid "%s star"
902
  msgstr ""
903
 
904
- #: includes/fs-plugin-info-dialog.php:898
905
  msgid "%s stars"
906
  msgstr ""
907
 
908
- #: includes/fs-plugin-info-dialog.php:909
909
  msgid "Click to see reviews that provided a rating of %s"
910
  msgstr ""
911
 
912
- #: includes/fs-plugin-info-dialog.php:922
913
  msgid "Contributors"
914
  msgstr ""
915
 
916
- #: includes/fs-plugin-info-dialog.php:950, includes/fs-plugin-info-dialog.php:952
917
  msgid "Warning"
918
  msgstr ""
919
 
920
- #: includes/fs-plugin-info-dialog.php:950
921
  msgid "This plugin has not been tested with your current version of WordPress."
922
  msgstr ""
923
 
924
- #: includes/fs-plugin-info-dialog.php:952
925
  msgid "This plugin has not been marked as compatible with your version of WordPress."
926
  msgstr ""
927
 
928
- #: includes/fs-plugin-info-dialog.php:971
929
  msgid "Paid add-on must be deployed to Freemius."
930
  msgstr ""
931
 
932
- #: includes/fs-plugin-info-dialog.php:972
933
  msgid "Add-on must be deployed to WordPress.org or Freemius."
934
  msgstr ""
935
 
936
- #: templates/account.php:81, templates/account/partials/site.php:295
937
  msgid "Downgrading your plan will immediately stop all future recurring payments and your %s plan license will expire in %s."
938
  msgstr ""
939
 
940
- #: templates/account.php:82
941
  msgid "Cancelling the trial will immediately block access to all premium features. Are you sure?"
942
  msgstr ""
943
 
944
- #: templates/account.php:83, templates/account/partials/site.php:296
945
  msgid "You can still enjoy all %s features but you will not have access to %s updates and support."
946
  msgstr ""
947
 
948
- #: templates/account.php:84, templates/account/partials/site.php:297
949
  msgid "Once your license expires you can still use the Free version but you will NOT have access to the %s features."
950
  msgstr ""
951
 
952
  #. translators: %s: Plan title (e.g. "Professional")
953
- #: templates/account.php:86, templates/account/partials/activate-license-button.php:31
954
  msgid "Activate %s Plan"
955
  msgstr ""
956
 
957
  #. translators: %s: Time period (e.g. Auto renews in "2 months")
958
- #: templates/account.php:89, templates/account/partials/site.php:275
959
  msgid "Auto renews in %s"
960
  msgstr ""
961
 
962
  #. translators: %s: Time period (e.g. Expires in "2 months")
963
- #: templates/account.php:91, templates/account/partials/site.php:277
964
  msgid "Expires in %s"
965
  msgstr ""
966
 
967
- #: templates/account.php:92
968
  msgctxt "as synchronize license"
969
  msgid "Sync License"
970
  msgstr ""
971
 
972
- #: templates/account.php:93
973
  msgid "Cancel Trial"
974
  msgstr ""
975
 
976
- #: templates/account.php:94
977
  msgid "Change Plan"
978
  msgstr ""
979
 
980
- #: templates/account.php:95
981
  msgctxt "verb"
982
  msgid "Upgrade"
983
  msgstr ""
984
 
985
- #: templates/account.php:97, templates/account/partials/site.php:298
986
  msgctxt "verb"
987
  msgid "Downgrade"
988
  msgstr ""
989
 
990
- #: templates/account.php:99, templates/add-ons.php:126, templates/plugin-info/features.php:72, templates/account/partials/site.php:31
991
  msgid "Free"
992
  msgstr ""
993
 
994
- #: templates/account.php:100
995
  msgid "Activate"
996
  msgstr ""
997
 
998
- #: templates/account.php:101, templates/debug.php:348, includes/customizer/class-fs-customizer-upsell-control.php:106
999
  msgctxt "as product pricing plan"
1000
  msgid "Plan"
1001
  msgstr ""
1002
 
1003
- #: templates/account.php:153
1004
  msgid "Free Trial"
1005
  msgstr ""
1006
 
1007
- #: templates/account.php:164
1008
  msgid "Account Details"
1009
  msgstr ""
1010
 
1011
- #: templates/account.php:174
1012
  msgid "Deleting the account will automatically deactivate your %s plan license so you can use it on other sites. If you want to terminate the recurring payments as well, click the \"Cancel\" button, and first \"Downgrade\" your account. Are you sure you would like to continue with the deletion?"
1013
  msgstr ""
1014
 
1015
- #: templates/account.php:176
1016
  msgid "Deletion is not temporary. Only delete if you no longer want to use this %s anymore. Are you sure you would like to continue with the deletion?"
1017
  msgstr ""
1018
 
1019
- #: templates/account.php:179
1020
  msgid "Delete Account"
1021
  msgstr ""
1022
 
1023
- #: templates/account.php:191, templates/account.php:675, templates/account/partials/deactivate-license-button.php:35
1024
  msgid "Deactivate License"
1025
  msgstr ""
1026
 
1027
- #: templates/account.php:209
1028
  msgid "Are you sure you want to proceed?"
1029
  msgstr ""
1030
 
1031
- #: templates/account.php:209
1032
  msgid "Cancel Subscription"
1033
  msgstr ""
1034
 
1035
- #: templates/account.php:238
1036
  msgctxt "as synchronize"
1037
  msgid "Sync"
1038
  msgstr ""
1039
 
1040
- #: templates/account.php:252, templates/debug.php:464
1041
  msgid "Name"
1042
  msgstr ""
1043
 
1044
- #: templates/account.php:258, templates/debug.php:465
1045
  msgid "Email"
1046
  msgstr ""
1047
 
1048
- #: templates/account.php:265, templates/debug.php:347, templates/debug.php:503
1049
  msgid "User ID"
1050
  msgstr ""
1051
 
1052
- #: templates/account.php:273
1053
  msgid "Site ID"
1054
  msgstr ""
1055
 
1056
- #: templates/account.php:276
1057
  msgid "No ID"
1058
  msgstr ""
1059
 
1060
- #: templates/account.php:281, templates/debug.php:233, templates/debug.php:349, templates/debug.php:430, templates/debug.php:467, templates/account/partials/site.php:219
1061
  msgid "Public Key"
1062
  msgstr ""
1063
 
1064
- #: templates/account.php:287, templates/debug.php:350, templates/debug.php:431, templates/debug.php:468, templates/account/partials/site.php:231
1065
  msgid "Secret Key"
1066
  msgstr ""
1067
 
1068
- #: templates/account.php:290
1069
  msgctxt "as secret encryption key missing"
1070
  msgid "No Secret"
1071
  msgstr ""
1072
 
1073
- #: templates/account.php:309, templates/account/partials/site.php:112, templates/account/partials/site.php:114
1074
  msgid "Trial"
1075
  msgstr ""
1076
 
1077
- #: templates/account.php:328, templates/debug.php:508, templates/account/partials/site.php:248
1078
  msgid "License Key"
1079
  msgstr ""
1080
 
1081
- #: templates/account.php:358
1082
  msgid "not verified"
1083
  msgstr ""
1084
 
1085
- #: templates/account.php:415
1086
  msgid "Premium version"
1087
  msgstr ""
1088
 
1089
- #: templates/account.php:417
1090
  msgid "Free version"
1091
  msgstr ""
1092
 
1093
- #: templates/account.php:429
1094
  msgid "Verify Email"
1095
  msgstr ""
1096
 
1097
- #: templates/account.php:440
1098
  msgid "Download %s Version"
1099
  msgstr ""
1100
 
1101
- #: templates/account.php:454, templates/account.php:896, templates/account/partials/site.php:237, templates/account/partials/site.php:255
1102
  msgctxt "verb"
1103
  msgid "Show"
1104
  msgstr ""
1105
 
1106
- #: templates/account.php:468
1107
  msgid "What is your %s?"
1108
  msgstr ""
1109
 
1110
- #: templates/account.php:476, templates/account/billing.php:27
1111
  msgctxt "verb"
1112
  msgid "Edit"
1113
  msgstr ""
1114
 
1115
- #: templates/account.php:489
1116
  msgid "Sites"
1117
  msgstr ""
1118
 
1119
- #: templates/account.php:500
1120
  msgid "Search by address"
1121
  msgstr ""
1122
 
1123
- #: templates/account.php:509, templates/account.php:555, templates/debug.php:226, templates/debug.php:341, templates/debug.php:426, templates/debug.php:463, templates/debug.php:501, templates/debug.php:580, templates/account/payments.php:35, templates/debug/logger.php:21
1124
  msgid "ID"
1125
  msgstr ""
1126
 
1127
- #: templates/account.php:510, templates/debug.php:344
1128
  msgid "Address"
1129
  msgstr ""
1130
 
1131
- #: templates/account.php:511
1132
  msgid "License"
1133
  msgstr ""
1134
 
1135
- #: templates/account.php:512
1136
  msgid "Plan"
1137
  msgstr ""
1138
 
1139
- #: templates/account.php:558
1140
  msgctxt "as software license"
1141
  msgid "License"
1142
  msgstr ""
1143
 
1144
- #: templates/account.php:635
1145
- msgid "Cancelled"
1146
- msgstr ""
1147
-
1148
- #: templates/account.php:640
1149
- msgid "Expired"
1150
- msgstr ""
1151
-
1152
- #: templates/account.php:645
1153
- msgid "No expiration"
1154
- msgstr ""
1155
-
1156
- #: templates/account.php:756, templates/account.php:812
1157
- msgid "Activate this add-on"
1158
- msgstr ""
1159
-
1160
- #: templates/account.php:833, templates/debug.php:408, templates/debug.php:486
1161
- msgctxt "verb"
1162
- msgid "Delete"
1163
- msgstr ""
1164
-
1165
- #: templates/account.php:890
1166
  msgctxt "verb"
1167
  msgid "Hide"
1168
  msgstr ""
1169
 
1170
- #: templates/account.php:925
1171
  msgid "Deactivating your license will block all premium features, but will enable activating the license on another site. Are you sure you want to proceed?"
1172
  msgstr ""
1173
 
@@ -1513,6 +1513,11 @@ msgstr ""
1513
  msgid "Blog ID"
1514
  msgstr ""
1515
 
 
 
 
 
 
1516
  #: templates/debug.php:422
1517
  msgid "Add Ons of module %s"
1518
  msgstr ""
@@ -2011,6 +2016,22 @@ msgstr ""
2011
  msgid "Last license"
2012
  msgstr ""
2013
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2014
  #: templates/account/partials/site.php:181
2015
  msgid "Owner Name"
2016
  msgstr ""
140
  msgid "No - just deactivate"
141
  msgstr ""
142
 
143
+ #: includes/class-freemius.php:3508, includes/class-freemius.php:4004, includes/class-freemius.php:5065, includes/class-freemius.php:10795, includes/class-freemius.php:13987, includes/class-freemius.php:14039, includes/class-freemius.php:14101, includes/class-freemius.php:16227, includes/class-freemius.php:16237, includes/class-freemius.php:16787, includes/class-freemius.php:16805, includes/class-freemius.php:16903, includes/class-freemius.php:17639, templates/add-ons.php:43
144
  msgctxt "exclamation"
145
  msgid "Oops"
146
  msgstr ""
149
  msgid "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."
150
  msgstr ""
151
 
152
+ #: includes/class-freemius.php:4001
153
  msgctxt "addonX cannot run without pluginY"
154
  msgid "%s cannot run without %s."
155
  msgstr ""
156
 
157
+ #: includes/class-freemius.php:4002
158
  msgctxt "addonX cannot run..."
159
  msgid "%s cannot run without the plugin."
160
  msgstr ""
161
 
162
+ #: includes/class-freemius.php:4114, includes/class-freemius.php:4139, includes/class-freemius.php:16876
163
  msgid "Unexpected API error. Please contact the %s's author with the following error."
164
  msgstr ""
165
 
166
+ #: includes/class-freemius.php:4753
167
  msgid "Premium %s version was successfully activated."
168
  msgstr ""
169
 
170
+ #: includes/class-freemius.php:4765, includes/class-freemius.php:6596
171
  msgctxt "Used to express elation, enthusiasm, or triumph (especially in electronic communication)."
172
  msgid "W00t"
173
  msgstr ""
174
 
175
+ #: includes/class-freemius.php:4780
176
  msgid "You have a %s license."
177
  msgstr ""
178
 
179
+ #: includes/class-freemius.php:4784, includes/class-freemius.php:13428, includes/class-freemius.php:13439, includes/class-freemius.php:16155, includes/class-freemius.php:16455, includes/class-freemius.php:16517, includes/class-freemius.php:16664
180
  msgctxt "interjection expressing joy or exuberance"
181
  msgid "Yee-haw"
182
  msgstr ""
183
 
184
+ #: includes/class-freemius.php:5048
185
  msgid "%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you'll have to purchase a license."
186
  msgstr ""
187
 
188
+ #: includes/class-freemius.php:5052
189
  msgid "%s is a premium only add-on. You have to purchase a license first before activating the plugin."
190
  msgstr ""
191
 
192
+ #: includes/class-freemius.php:5061, templates/add-ons.php:99, templates/account/partials/addon.php:281
193
  msgid "More information about %s"
194
  msgstr ""
195
 
196
+ #: includes/class-freemius.php:5062
197
  msgid "Purchase License"
198
  msgstr ""
199
 
200
+ #: includes/class-freemius.php:5973, templates/connect.php:153
201
  msgid "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 %s."
202
  msgstr ""
203
 
204
+ #: includes/class-freemius.php:5977
205
  msgid "start the trial"
206
  msgstr ""
207
 
208
+ #: includes/class-freemius.php:5978, templates/connect.php:157
209
  msgid "complete the install"
210
  msgstr ""
211
 
212
+ #: includes/class-freemius.php:6079
213
  msgid "You are just one step away - %s"
214
  msgstr ""
215
 
216
+ #: includes/class-freemius.php:6082
217
  msgctxt "%s - plugin name. As complete \"PluginX\" activation now"
218
  msgid "Complete \"%s\" Activation Now"
219
  msgstr ""
220
 
221
+ #: includes/class-freemius.php:6161
222
  msgid "We made a few tweaks to the %s, %s"
223
  msgstr ""
224
 
225
+ #: includes/class-freemius.php:6165
226
  msgid "Opt in to make \"%s\" Better!"
227
  msgstr ""
228
 
229
+ #: includes/class-freemius.php:6595
230
  msgid "The upgrade of %s was successfully completed."
231
  msgstr ""
232
 
233
+ #: includes/class-freemius.php:8310, includes/class-fs-plugin-updater.php:505, includes/class-fs-plugin-updater.php:657, includes/class-fs-plugin-updater.php:663, templates/auto-installation.php:32
234
  msgid "Add-On"
235
  msgstr ""
236
 
237
+ #: includes/class-freemius.php:8312, templates/debug.php:336, templates/debug.php:497
238
  msgid "Plugin"
239
  msgstr ""
240
 
241
+ #: includes/class-freemius.php:8313, templates/debug.php:336, templates/debug.php:497, templates/forms/deactivation/form.php:64
242
  msgid "Theme"
243
  msgstr ""
244
 
245
+ #: includes/class-freemius.php:10662
246
  msgid "invalid_site_details_collection"
247
  msgstr ""
248
 
249
+ #: includes/class-freemius.php:10782
250
  msgid "We couldn't find your email address in the system, are you sure it's the right address?"
251
  msgstr ""
252
 
253
+ #: includes/class-freemius.php:10784
254
  msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
255
  msgstr ""
256
 
257
+ #: includes/class-freemius.php:11010
258
  msgid "Account is pending activation."
259
  msgstr ""
260
 
261
+ #: includes/class-freemius.php:13410
262
  msgid "%s activation was successfully completed."
263
  msgstr ""
264
 
265
+ #: includes/class-freemius.php:13424
266
  msgid "Your account was successfully activated with the %s plan."
267
  msgstr ""
268
 
269
+ #: includes/class-freemius.php:13435, includes/class-freemius.php:16513
270
  msgid "Your trial has been successfully started."
271
  msgstr ""
272
 
273
+ #: includes/class-freemius.php:13985, includes/class-freemius.php:14037, includes/class-freemius.php:14099
274
  msgid "Couldn't activate %s."
275
  msgstr ""
276
 
277
+ #: includes/class-freemius.php:13986, includes/class-freemius.php:14038, includes/class-freemius.php:14100
278
  msgid "Please contact us with the following message:"
279
  msgstr ""
280
 
281
+ #: includes/class-freemius.php:14447, includes/class-freemius.php:18703
282
  msgid "Upgrade"
283
  msgstr ""
284
 
285
+ #: includes/class-freemius.php:14453
286
  msgid "Start Trial"
287
  msgstr ""
288
 
289
+ #: includes/class-freemius.php:14455
290
  msgid "Pricing"
291
  msgstr ""
292
 
293
+ #: includes/class-freemius.php:14515, includes/class-freemius.php:14517
294
  msgid "Affiliation"
295
  msgstr ""
296
 
297
+ #: includes/class-freemius.php:14537, includes/class-freemius.php:14539, templates/account.php:146, templates/debug.php:301
298
  msgid "Account"
299
  msgstr ""
300
 
301
+ #: includes/class-freemius.php:14550, includes/class-freemius.php:14552, includes/customizer/class-fs-customizer-support-section.php:60
302
  msgid "Contact Us"
303
  msgstr ""
304
 
305
+ #: includes/class-freemius.php:14562, includes/class-freemius.php:14564, includes/class-freemius.php:18713, templates/account.php:96, templates/account/partials/addon.php:37
306
  msgid "Add-Ons"
307
  msgstr ""
308
 
309
+ #: includes/class-freemius.php:14595, templates/pricing.php:97
310
  msgctxt "noun"
311
  msgid "Pricing"
312
  msgstr ""
313
 
314
+ #: includes/class-freemius.php:14788, includes/customizer/class-fs-customizer-support-section.php:67
315
  msgid "Support Forum"
316
  msgstr ""
317
 
318
+ #: includes/class-freemius.php:15573
319
  msgid "Your email has been successfully verified - you are AWESOME!"
320
  msgstr ""
321
 
322
+ #: includes/class-freemius.php:15574
323
  msgctxt "a positive response"
324
  msgid "Right on"
325
  msgstr ""
326
 
327
+ #: includes/class-freemius.php:16146
328
  msgid "Your %s Add-on plan was successfully upgraded."
329
  msgstr ""
330
 
331
+ #: includes/class-freemius.php:16148
332
  msgid "%s Add-on was successfully purchased."
333
  msgstr ""
334
 
335
+ #: includes/class-freemius.php:16151
336
  msgid "Download the latest version"
337
  msgstr ""
338
 
339
+ #: includes/class-freemius.php:16223
340
  msgctxt "%1s - plugin title, %2s - API domain"
341
  msgid "Your server is blocking the access to Freemius' API, which is crucial for %1s synchronization. Please contact your host to whitelist %2s"
342
  msgstr ""
343
 
344
+ #: includes/class-freemius.php:16226, includes/class-freemius.php:16635, includes/class-freemius.php:16700
345
  msgid "Error received from the server:"
346
  msgstr ""
347
 
348
+ #: includes/class-freemius.php:16236
349
  msgid "It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again."
350
  msgstr ""
351
 
352
+ #: includes/class-freemius.php:16418, includes/class-freemius.php:16640, includes/class-freemius.php:16683
353
  msgctxt "something somebody says when they are thinking about what you have just said."
354
  msgid "Hmm"
355
  msgstr ""
356
 
357
+ #: includes/class-freemius.php:16431
358
  msgid "It looks like you are still on the %s plan. If you did upgrade or change your plan, it's probably an issue on our side - sorry."
359
  msgstr ""
360
 
361
+ #: includes/class-freemius.php:16432, templates/account.php:98, templates/add-ons.php:130, templates/account/partials/addon.php:39
362
  msgctxt "trial period"
363
  msgid "Trial"
364
  msgstr ""
365
 
366
+ #: includes/class-freemius.php:16437
367
  msgid "I have upgraded my account but when I try to Sync the License, the plan remains %s."
368
  msgstr ""
369
 
370
+ #: includes/class-freemius.php:16441, includes/class-freemius.php:16495
371
  msgid "Please contact us here"
372
  msgstr ""
373
 
374
+ #: includes/class-freemius.php:16451
375
  msgid "Your plan was successfully upgraded."
376
  msgstr ""
377
 
378
+ #: includes/class-freemius.php:16468
379
  msgid "Your plan was successfully changed to %s."
380
  msgstr ""
381
 
382
+ #: includes/class-freemius.php:16483
383
  msgid "Your license has expired. You can still continue using the free %s forever."
384
  msgstr ""
385
 
386
+ #: includes/class-freemius.php:16491
387
  msgid "Your license has been cancelled. If you think it's a mistake, please contact support."
388
  msgstr ""
389
 
390
+ #: includes/class-freemius.php:16504
391
  msgid "Your license has expired. You can still continue using all the %s features, but you'll need to renew your license to continue getting updates and support."
392
  msgstr ""
393
 
394
+ #: includes/class-freemius.php:16526
395
  msgid "Your trial has expired. You can still continue using all our free features."
396
  msgstr ""
397
 
398
+ #: includes/class-freemius.php:16631
399
  msgid "It looks like the license could not be activated."
400
  msgstr ""
401
 
402
+ #: includes/class-freemius.php:16661
403
  msgid "Your license was successfully activated."
404
  msgstr ""
405
 
406
+ #: includes/class-freemius.php:16687
407
  msgid "It looks like your site currently doesn't have an active license."
408
  msgstr ""
409
 
410
+ #: includes/class-freemius.php:16699
411
  msgid "It looks like the license deactivation failed."
412
  msgstr ""
413
 
414
+ #: includes/class-freemius.php:16727
415
  msgid "Your license was successfully deactivated, you are back to the %s plan."
416
  msgstr ""
417
 
418
+ #: includes/class-freemius.php:16728
419
  msgid "O.K"
420
  msgstr ""
421
 
422
+ #: includes/class-freemius.php:16776
423
  msgid "Your plan was successfully downgraded. Your %s plan license will expire in %s."
424
  msgstr ""
425
 
426
+ #: includes/class-freemius.php:16786
427
  msgid "Seems like we are having some temporary issue with your plan downgrade. Please try again in few minutes."
428
  msgstr ""
429
 
430
+ #: includes/class-freemius.php:16810
431
  msgid "You are already running the %s in a trial mode."
432
  msgstr ""
433
 
434
+ #: includes/class-freemius.php:16821
435
  msgid "You already utilized a trial before."
436
  msgstr ""
437
 
438
+ #: includes/class-freemius.php:16835
439
  msgid "Plan %s do not exist, therefore, can't start a trial."
440
  msgstr ""
441
 
442
+ #: includes/class-freemius.php:16846
443
  msgid "Plan %s does not support a trial period."
444
  msgstr ""
445
 
446
+ #: includes/class-freemius.php:16857
447
  msgid "None of the %s's plans supports a trial period."
448
  msgstr ""
449
 
450
+ #: includes/class-freemius.php:16907
451
  msgid "It looks like you are not in trial mode anymore so there's nothing to cancel :)"
452
  msgstr ""
453
 
454
+ #: includes/class-freemius.php:16958
455
  msgid "Your %s free trial was successfully cancelled."
456
  msgstr ""
457
 
458
+ #: includes/class-freemius.php:16963
459
  msgid "Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes."
460
  msgstr ""
461
 
462
+ #: includes/class-freemius.php:17247
463
  msgid "Version %s was released."
464
  msgstr ""
465
 
466
+ #: includes/class-freemius.php:17247
467
  msgid "Please download %s."
468
  msgstr ""
469
 
470
+ #: includes/class-freemius.php:17254
471
  msgid "the latest %s version here"
472
  msgstr ""
473
 
474
+ #: includes/class-freemius.php:17259
475
  msgid "New"
476
  msgstr ""
477
 
478
+ #: includes/class-freemius.php:17264
479
  msgid "Seems like you got the latest release."
480
  msgstr ""
481
 
482
+ #: includes/class-freemius.php:17265
483
  msgid "You are all good!"
484
  msgstr ""
485
 
486
+ #: includes/class-freemius.php:17531
487
  msgid "Verification mail was just sent to %s. If you can't find it after 5 min, please check your spam box."
488
  msgstr ""
489
 
490
+ #: includes/class-freemius.php:17666
491
  msgid "Site successfully opted in."
492
  msgstr ""
493
 
494
+ #: includes/class-freemius.php:17667, includes/class-freemius.php:18444
495
  msgid "Awesome"
496
  msgstr ""
497
 
498
+ #: includes/class-freemius.php:17683, templates/forms/optout.php:32
499
  msgid "We appreciate your help in making the %s better by letting us track some usage data."
500
  msgstr ""
501
 
502
+ #: includes/class-freemius.php:17684
503
  msgid "Thank you!"
504
  msgstr ""
505
 
506
+ #: includes/class-freemius.php:17691
507
  msgid "We will no longer be sending any usage data of %s on %s to %s."
508
  msgstr ""
509
 
510
+ #: includes/class-freemius.php:17806
511
  msgid "Please check your mailbox, you should receive an email via %s to confirm the ownership change. From security reasons, you must confirm the change within the next 15 min. If you cannot find the email, please check your spam folder."
512
  msgstr ""
513
 
514
+ #: includes/class-freemius.php:17812
515
  msgid "Thanks for confirming the ownership change. An email was just sent to %s for final approval."
516
  msgstr ""
517
 
518
+ #: includes/class-freemius.php:17817
519
  msgid "%s is the new owner of the account."
520
  msgstr ""
521
 
522
+ #: includes/class-freemius.php:17819
523
  msgctxt "as congratulations"
524
  msgid "Congrats"
525
  msgstr ""
526
 
527
+ #: includes/class-freemius.php:17839
528
  msgid "Sorry, we could not complete the email update. Another user with the same email is already registered."
529
  msgstr ""
530
 
531
+ #: includes/class-freemius.php:17840
532
  msgid "If you would like to give up the ownership of the %s's account to %s click the Change Ownership button."
533
  msgstr ""
534
 
535
+ #: includes/class-freemius.php:17847
536
  msgid "Change Ownership"
537
  msgstr ""
538
 
539
+ #: includes/class-freemius.php:17855
540
  msgid "Your email was successfully updated. You should receive an email with confirmation instructions in few moments."
541
  msgstr ""
542
 
543
+ #: includes/class-freemius.php:17867
544
  msgid "Please provide your full name."
545
  msgstr ""
546
 
547
+ #: includes/class-freemius.php:17872
548
  msgid "Your name was successfully updated."
549
  msgstr ""
550
 
551
+ #: includes/class-freemius.php:17933
552
  msgid "You have successfully updated your %s."
553
  msgstr ""
554
 
555
+ #: includes/class-freemius.php:18073
556
  msgid "Just letting you know that the add-ons information of %s is being pulled from an external server."
557
  msgstr ""
558
 
559
+ #: includes/class-freemius.php:18074
560
  msgctxt "advance notice of something that will need attention."
561
  msgid "Heads up"
562
  msgstr ""
563
 
564
+ #: includes/class-freemius.php:18484
565
  msgctxt "exclamation"
566
  msgid "Hey"
567
  msgstr ""
568
 
569
+ #: includes/class-freemius.php:18484
570
  msgid "How do you like %s so far? Test all our %s premium features with a %d-day free trial."
571
  msgstr ""
572
 
573
+ #: includes/class-freemius.php:18492
574
  msgid "No commitment for %s days - cancel anytime!"
575
  msgstr ""
576
 
577
+ #: includes/class-freemius.php:18493
578
  msgid "No credit card required"
579
  msgstr ""
580
 
581
+ #: includes/class-freemius.php:18500, templates/forms/trial-start.php:53
582
  msgctxt "call to action"
583
  msgid "Start free trial"
584
  msgstr ""
585
 
586
+ #: includes/class-freemius.php:18577
587
  msgid "Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!"
588
  msgstr ""
589
 
590
+ #: includes/class-freemius.php:18586
591
  msgid "Learn more"
592
  msgstr ""
593
 
594
+ #: includes/class-freemius.php:18738, templates/account.php:394, templates/account.php:497, templates/connect.php:161, templates/connect.php:371, templates/forms/license-activation.php:24, templates/account/partials/addon.php:229
595
  msgid "Activate License"
596
  msgstr ""
597
 
598
+ #: includes/class-freemius.php:18739, templates/account.php:457, templates/account.php:496, templates/account/partials/site.php:256
599
  msgid "Change License"
600
  msgstr ""
601
 
602
+ #: includes/class-freemius.php:18809, templates/account/partials/site.php:161
603
  msgid "Opt Out"
604
  msgstr ""
605
 
606
+ #: includes/class-freemius.php:18811, includes/class-freemius.php:18816, templates/account/partials/site.php:43, templates/account/partials/site.php:161
607
  msgid "Opt In"
608
  msgstr ""
609
 
610
+ #: includes/class-freemius.php:19008
611
  msgid "Please follow these steps to complete the upgrade"
612
  msgstr ""
613
 
614
+ #: includes/class-freemius.php:19012
615
  msgid "Download the latest %s version"
616
  msgstr ""
617
 
618
+ #: includes/class-freemius.php:19016
619
  msgid "Upload and activate the downloaded version"
620
  msgstr ""
621
 
622
+ #: includes/class-freemius.php:19018
623
  msgid "How to upload and activate?"
624
  msgstr ""
625
 
626
+ #: includes/class-freemius.php:19063
627
  msgid "%sClick here%s to choose the sites where you'd like to activate the license on."
628
  msgstr ""
629
 
630
+ #: includes/class-freemius.php:19224
631
  msgid "Auto installation only works for opted-in users."
632
  msgstr ""
633
 
634
+ #: includes/class-freemius.php:19234, includes/class-freemius.php:19267, includes/class-fs-plugin-updater.php:637, includes/class-fs-plugin-updater.php:651
635
  msgid "Invalid module ID."
636
  msgstr ""
637
 
638
+ #: includes/class-freemius.php:19243, includes/class-fs-plugin-updater.php:671
639
  msgid "Premium version already active."
640
  msgstr ""
641
 
642
+ #: includes/class-freemius.php:19250
643
  msgid "You do not have a valid license to access the premium version."
644
  msgstr ""
645
 
646
+ #: includes/class-freemius.php:19257
647
  msgid "Plugin is a \"Serviceware\" which means it does not have a premium code version."
648
  msgstr ""
649
 
650
+ #: includes/class-freemius.php:19275, includes/class-fs-plugin-updater.php:670
651
  msgid "Premium add-on version already installed."
652
  msgstr ""
653
 
654
+ #: includes/class-freemius.php:19620
655
  msgid "View paid features"
656
  msgstr ""
657
 
671
  msgid "The remote plugin package does not contain a folder with the desired slug and renaming did not work."
672
  msgstr ""
673
 
674
+ #: includes/fs-plugin-info-dialog.php:336, templates/account/partials/addon.php:285
675
  msgctxt "verb"
676
  msgid "Purchase"
677
  msgstr ""
678
 
679
+ #: includes/fs-plugin-info-dialog.php:339
680
  msgid "Start my free %s"
681
  msgstr ""
682
 
683
+ #: includes/fs-plugin-info-dialog.php:380
684
+ msgid "Install Free Version Now"
685
+ msgstr ""
686
+
687
+ #: includes/fs-plugin-info-dialog.php:381, templates/auto-installation.php:111, templates/account/partials/addon.php:265, templates/account/partials/addon.php:315
688
+ msgid "Install Now"
689
+ msgstr ""
690
+
691
+ #: includes/fs-plugin-info-dialog.php:392
692
+ msgctxt "as download latest version"
693
+ msgid "Download Latest Free Version"
694
+ msgstr ""
695
+
696
+ #: includes/fs-plugin-info-dialog.php:393, templates/account.php:80, templates/account/partials/addon.php:21
697
  msgctxt "as download latest version"
698
  msgid "Download Latest"
699
  msgstr ""
700
 
701
+ #: includes/fs-plugin-info-dialog.php:403
702
+ msgid "Install Free Version Update Now"
703
  msgstr ""
704
 
705
+ #: includes/fs-plugin-info-dialog.php:404, templates/account.php:448
706
  msgid "Install Update Now"
707
  msgstr ""
708
 
709
+ #: includes/fs-plugin-info-dialog.php:415
710
+ msgid "Newer Free Version (%s) Installed"
711
+ msgstr ""
712
+
713
+ #: includes/fs-plugin-info-dialog.php:416
714
  msgid "Newer Version (%s) Installed"
715
  msgstr ""
716
 
717
+ #: includes/fs-plugin-info-dialog.php:424
718
+ msgid "Latest Free Version Installed"
719
+ msgstr ""
720
+
721
+ #: includes/fs-plugin-info-dialog.php:425
722
  msgid "Latest Version Installed"
723
  msgstr ""
724
 
725
+ #: includes/fs-plugin-info-dialog.php:580
726
  msgctxt "Plugin installer section title"
727
  msgid "Description"
728
  msgstr ""
729
 
730
+ #: includes/fs-plugin-info-dialog.php:581
731
  msgctxt "Plugin installer section title"
732
  msgid "Installation"
733
  msgstr ""
734
 
735
+ #: includes/fs-plugin-info-dialog.php:582
736
  msgctxt "Plugin installer section title"
737
  msgid "FAQ"
738
  msgstr ""
739
 
740
+ #: includes/fs-plugin-info-dialog.php:583, templates/plugin-info/description.php:55
741
  msgid "Screenshots"
742
  msgstr ""
743
 
744
+ #: includes/fs-plugin-info-dialog.php:584
745
  msgctxt "Plugin installer section title"
746
  msgid "Changelog"
747
  msgstr ""
748
 
749
+ #: includes/fs-plugin-info-dialog.php:585
750
  msgctxt "Plugin installer section title"
751
  msgid "Reviews"
752
  msgstr ""
753
 
754
+ #: includes/fs-plugin-info-dialog.php:586
755
  msgctxt "Plugin installer section title"
756
  msgid "Other Notes"
757
  msgstr ""
758
 
759
+ #: includes/fs-plugin-info-dialog.php:601
760
  msgctxt "Plugin installer section title"
761
  msgid "Features & Pricing"
762
  msgstr ""
763
 
764
+ #: includes/fs-plugin-info-dialog.php:611
765
  msgid "Plugin Install"
766
  msgstr ""
767
 
768
+ #: includes/fs-plugin-info-dialog.php:683
769
  msgctxt "e.g. Professional Plan"
770
  msgid "%s Plan"
771
  msgstr ""
772
 
773
+ #: includes/fs-plugin-info-dialog.php:709
774
  msgctxt "e.g. the best product"
775
  msgid "Best"
776
  msgstr ""
777
 
778
+ #: includes/fs-plugin-info-dialog.php:715, includes/fs-plugin-info-dialog.php:735
779
  msgctxt "as every month"
780
  msgid "Monthly"
781
  msgstr ""
782
 
783
+ #: includes/fs-plugin-info-dialog.php:718
784
  msgctxt "as once a year"
785
  msgid "Annual"
786
  msgstr ""
787
 
788
+ #: includes/fs-plugin-info-dialog.php:721
789
  msgid "Lifetime"
790
  msgstr ""
791
 
792
+ #: includes/fs-plugin-info-dialog.php:735, includes/fs-plugin-info-dialog.php:737, includes/fs-plugin-info-dialog.php:739
793
  msgctxt "e.g. billed monthly"
794
  msgid "Billed %s"
795
  msgstr ""
796
 
797
+ #: includes/fs-plugin-info-dialog.php:737
798
  msgctxt "as once a year"
799
  msgid "Annually"
800
  msgstr ""
801
 
802
+ #: includes/fs-plugin-info-dialog.php:739
803
  msgctxt "as once a year"
804
  msgid "Once"
805
  msgstr ""
806
 
807
+ #: includes/fs-plugin-info-dialog.php:745
808
  msgid "Single Site License"
809
  msgstr ""
810
 
811
+ #: includes/fs-plugin-info-dialog.php:747
812
  msgid "Unlimited Licenses"
813
  msgstr ""
814
 
815
+ #: includes/fs-plugin-info-dialog.php:749
816
  msgid "Up to %s Sites"
817
  msgstr ""
818
 
819
+ #: includes/fs-plugin-info-dialog.php:759, templates/plugin-info/features.php:82
820
  msgctxt "as monthly period"
821
  msgid "mo"
822
  msgstr ""
823
 
824
+ #: includes/fs-plugin-info-dialog.php:766, templates/plugin-info/features.php:80
825
  msgctxt "as annual period"
826
  msgid "year"
827
  msgstr ""
828
 
829
+ #: includes/fs-plugin-info-dialog.php:820
830
  msgctxt "noun"
831
  msgid "Price"
832
  msgstr ""
833
 
834
+ #: includes/fs-plugin-info-dialog.php:868
835
  msgid "Save %s"
836
  msgstr ""
837
 
838
+ #: includes/fs-plugin-info-dialog.php:878
839
  msgid "No commitment for %s - cancel anytime"
840
  msgstr ""
841
 
842
+ #: includes/fs-plugin-info-dialog.php:881
843
  msgid "After your free %s, pay as little as %s"
844
  msgstr ""
845
 
846
+ #: includes/fs-plugin-info-dialog.php:892
847
  msgid "Details"
848
  msgstr ""
849
 
850
+ #: includes/fs-plugin-info-dialog.php:896, templates/account.php:87, templates/debug.php:191, templates/debug.php:228, templates/debug.php:429, templates/account/partials/addon.php:28
851
  msgctxt "product version"
852
  msgid "Version"
853
  msgstr ""
854
 
855
+ #: includes/fs-plugin-info-dialog.php:903
856
  msgctxt "as the plugin author"
857
  msgid "Author"
858
  msgstr ""
859
 
860
+ #: includes/fs-plugin-info-dialog.php:910
861
  msgid "Last Updated"
862
  msgstr ""
863
 
864
+ #: includes/fs-plugin-info-dialog.php:915
865
  msgctxt "x-ago"
866
  msgid "%s ago"
867
  msgstr ""
868
 
869
+ #: includes/fs-plugin-info-dialog.php:924
870
  msgid "Requires WordPress Version"
871
  msgstr ""
872
 
873
+ #: includes/fs-plugin-info-dialog.php:925
874
  msgid "%s or higher"
875
  msgstr ""
876
 
877
+ #: includes/fs-plugin-info-dialog.php:932
878
  msgid "Compatible up to"
879
  msgstr ""
880
 
881
+ #: includes/fs-plugin-info-dialog.php:940
882
  msgid "Downloaded"
883
  msgstr ""
884
 
885
+ #: includes/fs-plugin-info-dialog.php:944
886
  msgid "%s time"
887
  msgstr ""
888
 
889
+ #: includes/fs-plugin-info-dialog.php:946
890
  msgid "%s times"
891
  msgstr ""
892
 
893
+ #: includes/fs-plugin-info-dialog.php:956
894
  msgid "WordPress.org Plugin Page"
895
  msgstr ""
896
 
897
+ #: includes/fs-plugin-info-dialog.php:964
898
  msgid "Plugin Homepage"
899
  msgstr ""
900
 
901
+ #: includes/fs-plugin-info-dialog.php:972, includes/fs-plugin-info-dialog.php:1054
902
  msgid "Donate to this plugin"
903
  msgstr ""
904
 
905
+ #: includes/fs-plugin-info-dialog.php:979
906
  msgid "Average Rating"
907
  msgstr ""
908
 
909
+ #: includes/fs-plugin-info-dialog.php:986
910
  msgid "based on %s"
911
  msgstr ""
912
 
913
+ #: includes/fs-plugin-info-dialog.php:990
914
  msgid "%s rating"
915
  msgstr ""
916
 
917
+ #: includes/fs-plugin-info-dialog.php:992
918
  msgid "%s ratings"
919
  msgstr ""
920
 
921
+ #: includes/fs-plugin-info-dialog.php:1007
922
  msgid "%s star"
923
  msgstr ""
924
 
925
+ #: includes/fs-plugin-info-dialog.php:1009
926
  msgid "%s stars"
927
  msgstr ""
928
 
929
+ #: includes/fs-plugin-info-dialog.php:1020
930
  msgid "Click to see reviews that provided a rating of %s"
931
  msgstr ""
932
 
933
+ #: includes/fs-plugin-info-dialog.php:1033
934
  msgid "Contributors"
935
  msgstr ""
936
 
937
+ #: includes/fs-plugin-info-dialog.php:1062, includes/fs-plugin-info-dialog.php:1064
938
  msgid "Warning"
939
  msgstr ""
940
 
941
+ #: includes/fs-plugin-info-dialog.php:1062
942
  msgid "This plugin has not been tested with your current version of WordPress."
943
  msgstr ""
944
 
945
+ #: includes/fs-plugin-info-dialog.php:1064
946
  msgid "This plugin has not been marked as compatible with your version of WordPress."
947
  msgstr ""
948
 
949
+ #: includes/fs-plugin-info-dialog.php:1083
950
  msgid "Paid add-on must be deployed to Freemius."
951
  msgstr ""
952
 
953
+ #: includes/fs-plugin-info-dialog.php:1084
954
  msgid "Add-on must be deployed to WordPress.org or Freemius."
955
  msgstr ""
956
 
957
+ #: templates/account.php:81, templates/account/partials/addon.php:22, templates/account/partials/site.php:295
958
  msgid "Downgrading your plan will immediately stop all future recurring payments and your %s plan license will expire in %s."
959
  msgstr ""
960
 
961
+ #: templates/account.php:82, templates/account/partials/addon.php:23
962
  msgid "Cancelling the trial will immediately block access to all premium features. Are you sure?"
963
  msgstr ""
964
 
965
+ #: templates/account.php:83, templates/account/partials/addon.php:24, templates/account/partials/site.php:296
966
  msgid "You can still enjoy all %s features but you will not have access to %s updates and support."
967
  msgstr ""
968
 
969
+ #: templates/account.php:84, templates/account/partials/addon.php:25, templates/account/partials/site.php:297
970
  msgid "Once your license expires you can still use the Free version but you will NOT have access to the %s features."
971
  msgstr ""
972
 
973
  #. translators: %s: Plan title (e.g. "Professional")
974
+ #: templates/account.php:86, templates/account/partials/activate-license-button.php:31, templates/account/partials/addon.php:27
975
  msgid "Activate %s Plan"
976
  msgstr ""
977
 
978
  #. translators: %s: Time period (e.g. Auto renews in "2 months")
979
+ #: templates/account.php:89, templates/account/partials/addon.php:30, templates/account/partials/site.php:275
980
  msgid "Auto renews in %s"
981
  msgstr ""
982
 
983
  #. translators: %s: Time period (e.g. Expires in "2 months")
984
+ #: templates/account.php:91, templates/account/partials/addon.php:32, templates/account/partials/site.php:277
985
  msgid "Expires in %s"
986
  msgstr ""
987
 
988
+ #: templates/account.php:92, templates/account/partials/addon.php:33
989
  msgctxt "as synchronize license"
990
  msgid "Sync License"
991
  msgstr ""
992
 
993
+ #: templates/account.php:93, templates/account/partials/addon.php:34
994
  msgid "Cancel Trial"
995
  msgstr ""
996
 
997
+ #: templates/account.php:94, templates/account/partials/addon.php:35
998
  msgid "Change Plan"
999
  msgstr ""
1000
 
1001
+ #: templates/account.php:95, templates/account/partials/addon.php:36
1002
  msgctxt "verb"
1003
  msgid "Upgrade"
1004
  msgstr ""
1005
 
1006
+ #: templates/account.php:97, templates/account/partials/addon.php:38, templates/account/partials/site.php:298
1007
  msgctxt "verb"
1008
  msgid "Downgrade"
1009
  msgstr ""
1010
 
1011
+ #: templates/account.php:99, templates/add-ons.php:126, templates/plugin-info/features.php:72, templates/account/partials/addon.php:40, templates/account/partials/site.php:31
1012
  msgid "Free"
1013
  msgstr ""
1014
 
1015
+ #: templates/account.php:100, templates/account/partials/addon.php:41
1016
  msgid "Activate"
1017
  msgstr ""
1018
 
1019
+ #: templates/account.php:101, templates/debug.php:348, includes/customizer/class-fs-customizer-upsell-control.php:106, templates/account/partials/addon.php:42
1020
  msgctxt "as product pricing plan"
1021
  msgid "Plan"
1022
  msgstr ""
1023
 
1024
+ #: templates/account.php:154
1025
  msgid "Free Trial"
1026
  msgstr ""
1027
 
1028
+ #: templates/account.php:165
1029
  msgid "Account Details"
1030
  msgstr ""
1031
 
1032
+ #: templates/account.php:175
1033
  msgid "Deleting the account will automatically deactivate your %s plan license so you can use it on other sites. If you want to terminate the recurring payments as well, click the \"Cancel\" button, and first \"Downgrade\" your account. Are you sure you would like to continue with the deletion?"
1034
  msgstr ""
1035
 
1036
+ #: templates/account.php:177
1037
  msgid "Deletion is not temporary. Only delete if you no longer want to use this %s anymore. Are you sure you would like to continue with the deletion?"
1038
  msgstr ""
1039
 
1040
+ #: templates/account.php:180
1041
  msgid "Delete Account"
1042
  msgstr ""
1043
 
1044
+ #: templates/account.php:192, templates/account/partials/addon.php:155, templates/account/partials/deactivate-license-button.php:35
1045
  msgid "Deactivate License"
1046
  msgstr ""
1047
 
1048
+ #: templates/account.php:210
1049
  msgid "Are you sure you want to proceed?"
1050
  msgstr ""
1051
 
1052
+ #: templates/account.php:210, templates/account/partials/addon.php:177
1053
  msgid "Cancel Subscription"
1054
  msgstr ""
1055
 
1056
+ #: templates/account.php:239
1057
  msgctxt "as synchronize"
1058
  msgid "Sync"
1059
  msgstr ""
1060
 
1061
+ #: templates/account.php:253, templates/debug.php:464
1062
  msgid "Name"
1063
  msgstr ""
1064
 
1065
+ #: templates/account.php:259, templates/debug.php:465
1066
  msgid "Email"
1067
  msgstr ""
1068
 
1069
+ #: templates/account.php:266, templates/debug.php:347, templates/debug.php:503
1070
  msgid "User ID"
1071
  msgstr ""
1072
 
1073
+ #: templates/account.php:274
1074
  msgid "Site ID"
1075
  msgstr ""
1076
 
1077
+ #: templates/account.php:277
1078
  msgid "No ID"
1079
  msgstr ""
1080
 
1081
+ #: templates/account.php:282, templates/debug.php:233, templates/debug.php:349, templates/debug.php:430, templates/debug.php:467, templates/account/partials/site.php:219
1082
  msgid "Public Key"
1083
  msgstr ""
1084
 
1085
+ #: templates/account.php:288, templates/debug.php:350, templates/debug.php:431, templates/debug.php:468, templates/account/partials/site.php:231
1086
  msgid "Secret Key"
1087
  msgstr ""
1088
 
1089
+ #: templates/account.php:291
1090
  msgctxt "as secret encryption key missing"
1091
  msgid "No Secret"
1092
  msgstr ""
1093
 
1094
+ #: templates/account.php:310, templates/account/partials/site.php:112, templates/account/partials/site.php:114
1095
  msgid "Trial"
1096
  msgstr ""
1097
 
1098
+ #: templates/account.php:329, templates/debug.php:508, templates/account/partials/site.php:248
1099
  msgid "License Key"
1100
  msgstr ""
1101
 
1102
+ #: templates/account.php:359
1103
  msgid "not verified"
1104
  msgstr ""
1105
 
1106
+ #: templates/account.php:416
1107
  msgid "Premium version"
1108
  msgstr ""
1109
 
1110
+ #: templates/account.php:418
1111
  msgid "Free version"
1112
  msgstr ""
1113
 
1114
+ #: templates/account.php:430
1115
  msgid "Verify Email"
1116
  msgstr ""
1117
 
1118
+ #: templates/account.php:441
1119
  msgid "Download %s Version"
1120
  msgstr ""
1121
 
1122
+ #: templates/account.php:455, templates/account.php:636, templates/account/partials/site.php:237, templates/account/partials/site.php:255
1123
  msgctxt "verb"
1124
  msgid "Show"
1125
  msgstr ""
1126
 
1127
+ #: templates/account.php:469
1128
  msgid "What is your %s?"
1129
  msgstr ""
1130
 
1131
+ #: templates/account.php:477, templates/account/billing.php:27
1132
  msgctxt "verb"
1133
  msgid "Edit"
1134
  msgstr ""
1135
 
1136
+ #: templates/account.php:490
1137
  msgid "Sites"
1138
  msgstr ""
1139
 
1140
+ #: templates/account.php:501
1141
  msgid "Search by address"
1142
  msgstr ""
1143
 
1144
+ #: templates/account.php:510, templates/account.php:558, templates/debug.php:226, templates/debug.php:341, templates/debug.php:426, templates/debug.php:463, templates/debug.php:501, templates/debug.php:580, templates/account/payments.php:35, templates/debug/logger.php:21
1145
  msgid "ID"
1146
  msgstr ""
1147
 
1148
+ #: templates/account.php:511, templates/debug.php:344
1149
  msgid "Address"
1150
  msgstr ""
1151
 
1152
+ #: templates/account.php:512
1153
  msgid "License"
1154
  msgstr ""
1155
 
1156
+ #: templates/account.php:513
1157
  msgid "Plan"
1158
  msgstr ""
1159
 
1160
+ #: templates/account.php:561
1161
  msgctxt "as software license"
1162
  msgid "License"
1163
  msgstr ""
1164
 
1165
+ #: templates/account.php:630
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1166
  msgctxt "verb"
1167
  msgid "Hide"
1168
  msgstr ""
1169
 
1170
+ #: templates/account.php:665
1171
  msgid "Deactivating your license will block all premium features, but will enable activating the license on another site. Are you sure you want to proceed?"
1172
  msgstr ""
1173
 
1513
  msgid "Blog ID"
1514
  msgstr ""
1515
 
1516
+ #: templates/debug.php:408, templates/debug.php:486, templates/account/partials/addon.php:332
1517
+ msgctxt "verb"
1518
+ msgid "Delete"
1519
+ msgstr ""
1520
+
1521
  #: templates/debug.php:422
1522
  msgid "Add Ons of module %s"
1523
  msgstr ""
2016
  msgid "Last license"
2017
  msgstr ""
2018
 
2019
+ #: templates/account/partials/addon.php:111
2020
+ msgid "Cancelled"
2021
+ msgstr ""
2022
+
2023
+ #: templates/account/partials/addon.php:116
2024
+ msgid "Expired"
2025
+ msgstr ""
2026
+
2027
+ #: templates/account/partials/addon.php:121
2028
+ msgid "No expiration"
2029
+ msgstr ""
2030
+
2031
+ #: templates/account/partials/addon.php:257, templates/account/partials/addon.php:310
2032
+ msgid "Activate this add-on"
2033
+ msgstr ""
2034
+
2035
  #: templates/account/partials/site.php:181
2036
  msgid "Owner Name"
2037
  msgstr ""
sdk/freemius/templates/account.php CHANGED
@@ -103,9 +103,10 @@
103
  $show_plan_row = true;
104
  $show_license_row = is_object( $license );
105
 
 
 
106
  if ( fs_is_network_admin() ) {
107
  $sites = Freemius::get_sites();
108
- $site_view_params = array();
109
  $all_installs_plan_id = null;
110
  $all_installs_license_id = ( $show_license_row ? $license->id : null );
111
  foreach ( $sites as $s ) {
@@ -518,10 +519,12 @@
518
  <div class="fs-table-body">
519
  <table class="widefat">
520
  <?php
521
- // for ($i = 0; $i < 5; $i++){
522
  foreach ( $site_view_params as $view_params ) {
523
- fs_require_template( 'account/partials/site.php', $view_params );
524
- } //} ?>
 
 
 
525
  </table>
526
  </div>
527
  </div>
@@ -564,283 +567,20 @@
564
  </thead>
565
  <tbody>
566
  <?php $odd = true;
567
- foreach ( $addons_to_show as $addon_id ) : ?>
568
- <?php
569
- $addon = $fs->get_addon( $addon_id );
570
- $is_addon_activated = $fs->is_addon_activated( $addon_id );
571
- $is_addon_connected = $fs->is_addon_connected( $addon_id );
572
-
573
- $fs_addon = $is_addon_connected ? freemius( $addon_id ) : false;
574
- if ( is_object( $fs_addon ) ) {
575
- $is_paying = $fs_addon->is_paying();
576
- $user = $fs_addon->get_user();
577
- $site = $fs_addon->get_site();
578
- $license = $fs_addon->_get_license();
579
- $subscription = ( is_object( $license ) ?
580
- $fs_addon->_get_subscription( $license->id ) :
581
- null );
582
- $plan = $fs_addon->get_plan();
583
- $is_active_subscription = ( is_object( $subscription ) && $subscription->is_active() );
584
- $is_paid_trial = $fs_addon->is_paid_trial();
585
- $show_upgrade = ( ! $is_paying && ! $is_paid_trial && ! $fs_addon->_has_premium_license() );
586
- $is_current_license_expired = is_object( $license ) && $license->is_expired();
587
- }
588
-
589
- // var_dump( $is_paid_trial, $license, $site, $subscription );
590
-
591
- ?>
592
- <tr<?php if ( $odd ) {
593
- echo ' class="alternate"';
594
- } ?>>
595
- <td>
596
- <!-- Title -->
597
- <?php echo $addon->title ?>
598
- </td>
599
- <?php if ( $is_addon_connected ) : ?>
600
- <?php // Add-on Installed ?>
601
- <?php $addon_site = $fs_addon->get_site(); ?>
602
- <td>
603
- <!-- ID -->
604
- <?php echo $addon_site->id ?>
605
- </td>
606
- <td>
607
- <!-- Version -->
608
- <?php echo $fs_addon->get_plugin_version() ?>
609
- </td>
610
- <td>
611
- <!-- Plan Title -->
612
- <?php echo strtoupper( is_string( $plan->name ) ? $plan->title : $free_text ) ?>
613
- </td>
614
- <td>
615
- <!-- Expiration -->
616
- <?php
617
- $tags = array();
618
-
619
- if ( $fs_addon->is_trial() ) {
620
- $tags[] = array( 'label' => $trial_text, 'type' => 'success' );
621
-
622
- $tags[] = array(
623
- 'label' => sprintf(
624
- ( $is_paid_trial ?
625
- $renews_in_text :
626
- $expires_in_text ),
627
- human_time_diff( time(), strtotime( $site->trial_ends ) )
628
- ),
629
- 'type' => ( $is_paid_trial ? 'success' : 'warn' )
630
- );
631
- } else {
632
- if ( is_object( $license ) ) {
633
- if ( $license->is_cancelled ) {
634
- $tags[] = array(
635
- 'label' => fs_text_inline( 'Cancelled', 'cancelled', $slug ),
636
- 'type' => 'error'
637
- );
638
- } else if ( $license->is_expired() ) {
639
- $tags[] = array(
640
- 'label' => fs_text_inline( 'Expired', 'expired', $slug ),
641
- 'type' => 'error'
642
- );
643
- } else if ( $license->is_lifetime() ) {
644
- $tags[] = array(
645
- 'label' => fs_text_inline( 'No expiration', 'no-expiration', $slug ),
646
- 'type' => 'success'
647
- );
648
- } else if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) {
649
- $tags[] = array(
650
- 'label' => sprintf( $expires_in_text, human_time_diff( time(), strtotime( $license->expiration ) ) ),
651
- 'type' => 'warn'
652
- );
653
- } else if ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) {
654
- $tags[] = array(
655
- 'label' => sprintf( $renews_in_text, human_time_diff( time(), strtotime( $subscription->next_payment ) ) ),
656
- 'type' => 'success'
657
- );
658
- }
659
- }
660
- }
661
-
662
- foreach ( $tags as $t ) {
663
- printf( '<label class="fs-tag fs-%s">%s</label>' . "\n", $t['type'], $t['label'] );
664
- }
665
- ?>
666
- </td>
667
- <?php
668
- $buttons = array();
669
- if ( $is_addon_activated ) {
670
- if ( $is_paying ) {
671
- $buttons[] = fs_ui_get_action_button(
672
- $fs->get_id(),
673
- 'account',
674
- 'deactivate_license',
675
- fs_text_inline( 'Deactivate License', 'deactivate-license', $slug ),
676
- array( 'plugin_id' => $addon_id ),
677
- false
678
- );
679
-
680
- $human_readable_license_expiration = human_time_diff( time(), strtotime( $license->expiration ) );
681
- $downgrade_confirmation_message = sprintf(
682
- $downgrade_x_confirm_text,
683
- $plan->title,
684
- $human_readable_license_expiration
685
- );
686
-
687
- $after_downgrade_message = ! $license->is_block_features ?
688
- sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs_addon->get_module_label( true ) ) :
689
- sprintf( $after_downgrade_blocking_text, $plan->title );
690
-
691
- if ( ! $license->is_lifetime() && $is_active_subscription ) {
692
- $buttons[] = fs_ui_get_action_button(
693
- $fs->get_id(),
694
- 'account',
695
- 'downgrade_account',
696
- $downgrade_text,
697
- array( 'plugin_id' => $addon_id ),
698
- false,
699
- false,
700
- false,
701
- false,
702
- ( $downgrade_confirmation_message . ' ' . $after_downgrade_message ),
703
- 'POST'
704
- );
705
- }
706
- } else if ( $is_paid_trial ) {
707
- $buttons[] = fs_ui_get_action_button(
708
- $fs->get_id(),
709
- 'account',
710
- 'cancel_trial',
711
- $cancel_trial_text,
712
- array( 'plugin_id' => $addon_id ),
713
- false,
714
- false,
715
- 'dashicons dashicons-download',
716
- $cancel_trial_confirm_text,
717
- 'POST'
718
- );
719
- } else {
720
- $premium_license = $fs_addon->_get_available_premium_license();
721
-
722
- if ( is_object( $premium_license ) ) {
723
- $site = $fs_addon->get_site();
724
-
725
- $buttons[] = fs_ui_get_action_button(
726
- $fs->get_id(),
727
- 'account',
728
- 'activate_license',
729
- sprintf( $activate_plan_text, $fs_addon->get_plan_title(), ( $site->is_localhost() && $premium_license->is_free_localhost ) ? '[localhost]' : ( 1 < $premium_license->left() ? $premium_license->left() . ' left' : '' ) ),
730
- array(
731
- 'plugin_id' => $addon_id,
732
- 'license_id' => $premium_license->id,
733
- )
734
- );
735
- }
736
- }
737
-
738
- if ( 0 == count( $buttons ) ) {
739
- // Add sync license only if non of the other CTAs are visible.
740
- $buttons[] = fs_ui_get_action_button(
741
- $fs->get_id(),
742
- 'account',
743
- $fs->get_unique_affix() . '_sync_license',
744
- $sync_license_text,
745
- array( 'plugin_id' => $addon_id ),
746
- false
747
- );
748
-
749
- }
750
- } else if ( ! $show_upgrade ) {
751
- if ( $fs->is_addon_installed( $addon_id ) ) {
752
- $addon_file = $fs->get_addon_basename( $addon_id );
753
- $buttons[] = sprintf(
754
- '<a class="button button-primary edit" href="%s" title="%s">%s</a>',
755
- wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ),
756
- fs_esc_attr_inline( 'Activate this add-on', 'activate-this-addon', $slug ),
757
- $activate_text
758
- );
759
- } else {
760
- if ( $fs->is_allowed_to_install() ) {
761
- $buttons[] = sprintf(
762
- '<a class="button button-primary edit" href="%s">%s</a>',
763
- wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ),
764
- fs_text_inline( 'Install Now', 'install-now', $slug )
765
- );
766
- } else {
767
- $buttons[] = sprintf(
768
- '<a target="_blank" class="button button-primary edit" href="%s">%s</a>',
769
- $fs->_get_latest_download_local_url( $addon_id ),
770
- esc_html( $download_latest_text )
771
- );
772
- }
773
- }
774
- }
775
-
776
- if ( $show_upgrade ) {
777
- $buttons[] = sprintf( '<a href="%s" class="thickbox button button-primary" aria-label="%s" data-title="%s"><i class="dashicons dashicons-cart"></i> %s</a>',
778
- esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
779
- '&TB_iframe=true&width=600&height=550' ) ),
780
- esc_attr( sprintf( fs_text_inline( 'More information about %s', 'more-information-about-x', $slug ), $addon->title ) ),
781
- esc_attr( $addon->title ),
782
- ( $fs_addon->has_free_plan() ?
783
- $upgrade_text :
784
- fs_text_x_inline( 'Purchase', 'verb', 'purchase', $slug ) )
785
- );
786
- }
787
-
788
- $buttons_count = count( $buttons );
789
- ?>
790
-
791
- <td>
792
- <!-- Actions -->
793
- <?php if ($buttons_count > 1) : ?>
794
- <div class="button-group">
795
- <?php endif ?>
796
- <?php foreach ( $buttons as $button ) : ?>
797
- <?php echo $button ?>
798
- <?php endforeach ?>
799
- <?php if ($buttons_count > 1) : ?>
800
- </div>
801
- <?php endif ?>
802
- </td>
803
- <?php else : ?>
804
- <?php // Add-on NOT Installed or was never connected.
805
- ?>
806
- <td colspan="4">
807
- <!-- Action -->
808
- <?php if ( $fs->is_addon_installed( $addon_id ) ) : ?>
809
- <?php $addon_file = $fs->get_addon_basename( $addon_id ) ?>
810
- <a class="button button-primary"
811
- href="<?php echo wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ) ?>"
812
- title="<?php fs_esc_attr_echo_inline( 'Activate this add-on', 'activate-this-addon', $slug ) ?>"
813
- class="edit"><?php echo esc_html( $activate_text ) ?></a>
814
- <?php else : ?>
815
- <?php if ( $fs->is_allowed_to_install() ) : ?>
816
- <a class="button button-primary"
817
- href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ) ?>"><?php fs_esc_html_echo_inline( 'Install Now', 'install-now', $slug ) ?></a>
818
- <?php else : ?>
819
- <a target="_blank" class="button button-primary"
820
- href="<?php echo $fs->_get_latest_download_local_url( $addon_id ) ?>"><?php echo esc_html( $download_latest_text ) ?></a>
821
- <?php endif ?>
822
- <?php endif ?>
823
- </td>
824
- <?php endif ?>
825
- <?php if ( ! $is_paying && defined( 'WP_FS__DEV_MODE' ) && WP_FS__DEV_MODE ) : ?>
826
- <td>
827
- <!-- Optional Delete Action -->
828
- <?php
829
- if ( $is_addon_activated ) {
830
- fs_ui_action_button(
831
- $fs->get_id(), 'account',
832
- 'delete_account',
833
- fs_text_x_inline( 'Delete', 'verb', 'delete', $slug ),
834
- array( 'plugin_id' => $addon_id ),
835
- false
836
- );
837
- }
838
- ?>
839
- </td>
840
- <?php endif ?>
841
- </tr>
842
- <?php $odd = ! $odd;
843
- endforeach ?>
844
  </tbody>
845
  </table>
846
  </div>
103
  $show_plan_row = true;
104
  $show_license_row = is_object( $license );
105
 
106
+ $site_view_params = array();
107
+
108
  if ( fs_is_network_admin() ) {
109
  $sites = Freemius::get_sites();
 
110
  $all_installs_plan_id = null;
111
  $all_installs_license_id = ( $show_license_row ? $license->id : null );
112
  foreach ( $sites as $s ) {
519
  <div class="fs-table-body">
520
  <table class="widefat">
521
  <?php
 
522
  foreach ( $site_view_params as $view_params ) {
523
+ fs_require_template(
524
+ 'account/partials/site.php',
525
+ $view_params
526
+ );
527
+ } ?>
528
  </table>
529
  </div>
530
  </div>
567
  </thead>
568
  <tbody>
569
  <?php $odd = true;
570
+ foreach ( $addons_to_show as $addon_id ) {
571
+ $addon_view_params = array(
572
+ 'parent_fs' => $fs,
573
+ 'addon_id' => $addon_id,
574
+ 'odd' => $odd,
575
+ );
576
+
577
+ fs_require_template(
578
+ 'account/partials/addon.php',
579
+ $addon_view_params
580
+ );
581
+
582
+ $odd = ! $odd;
583
+ } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
  </tbody>
585
  </table>
586
  </div>
sdk/freemius/templates/account/partials/addon.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var array $VARS
4
+ * @var Freemius $fs
5
+ */
6
+ $fs = $VARS['parent_fs'];
7
+ $addon_id = $VARS['addon_id'];
8
+ $odd = $VARS['odd'];
9
+ $slug = $fs->get_slug();
10
+
11
+
12
+ $addon = $fs->get_addon( $addon_id );
13
+ $is_addon_activated = $fs->is_addon_activated( $addon_id );
14
+ $is_addon_connected = $fs->is_addon_connected( $addon_id );
15
+
16
+ $fs_addon = $is_addon_connected ?
17
+ freemius( $addon_id ) :
18
+ false;
19
+
20
+ // Aliases.
21
+ $download_latest_text = fs_text_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $slug );
22
+ $downgrade_x_confirm_text = fs_text_inline( 'Downgrading your plan will immediately stop all future recurring payments and your %s plan license will expire in %s.', 'downgrade-x-confirm', $slug );
23
+ $cancel_trial_confirm_text = fs_text_inline( 'Cancelling the trial will immediately block access to all premium features. Are you sure?', 'cancel-trial-confirm', $slug );
24
+ $after_downgrade_non_blocking_text = fs_text_inline( 'You can still enjoy all %s features but you will not have access to %s updates and support.', 'after-downgrade-non-blocking', $slug );
25
+ $after_downgrade_blocking_text = fs_text_inline( 'Once your license expires you can still use the Free version but you will NOT have access to the %s features.', 'after-downgrade-blocking', $slug );
26
+ /* translators: %s: Plan title (e.g. "Professional") */
27
+ $activate_plan_text = fs_text_inline( 'Activate %s Plan', 'activate-x-plan', $slug );
28
+ $version_text = fs_text_x_inline( 'Version', 'product version', 'version', $slug );
29
+ /* translators: %s: Time period (e.g. Auto renews in "2 months") */
30
+ $renews_in_text = fs_text_inline( 'Auto renews in %s', 'renews-in', $slug );
31
+ /* translators: %s: Time period (e.g. Expires in "2 months") */
32
+ $expires_in_text = fs_text_inline( 'Expires in %s', 'expires-in', $slug );
33
+ $sync_license_text = fs_text_x_inline( 'Sync License', 'as synchronize license', 'sync-license', $slug );
34
+ $cancel_trial_text = fs_text_inline( 'Cancel Trial', 'cancel-trial', $slug );
35
+ $change_plan_text = fs_text_inline( 'Change Plan', 'change-plan', $slug );
36
+ $upgrade_text = fs_text_x_inline( 'Upgrade', 'verb', 'upgrade', $slug );
37
+ $addons_text = fs_text_inline( 'Add-Ons', 'add-ons', $slug );
38
+ $downgrade_text = fs_text_x_inline( 'Downgrade', 'verb', 'downgrade', $slug );
39
+ $trial_text = fs_text_x_inline( 'Trial', 'trial period', 'trial', $slug );
40
+ $free_text = fs_text_inline( 'Free', 'free', $slug );
41
+ $activate_text = fs_text_inline( 'Activate', 'activate', $slug );
42
+ $plan_text = fs_text_x_inline( 'Plan', 'as product pricing plan', 'plan', $slug );
43
+
44
+ // Defaults.
45
+ $plan = null;
46
+ $is_paid_trial = false;
47
+ $license = null;
48
+ $site = null;
49
+ $is_active_subscription = false;
50
+ $subscription = null;
51
+ $is_paying = false;
52
+
53
+ if ( is_object( $fs_addon ) ) {
54
+ $is_paying = $fs_addon->is_paying();
55
+ $user = $fs_addon->get_user();
56
+ $site = $fs_addon->get_site();
57
+ $license = $fs_addon->_get_license();
58
+ $subscription = ( is_object( $license ) ?
59
+ $fs_addon->_get_subscription( $license->id ) :
60
+ null );
61
+ $plan = $fs_addon->get_plan();
62
+ $is_active_subscription = ( is_object( $subscription ) && $subscription->is_active() );
63
+ $is_paid_trial = $fs_addon->is_paid_trial();
64
+ $show_upgrade = ( ! $is_paying && ! $is_paid_trial && ! $fs_addon->_has_premium_license() );
65
+ $is_current_license_expired = is_object( $license ) && $license->is_expired();
66
+ }
67
+ ?>
68
+ <tr<?php if ( $odd ) {
69
+ echo ' class="alternate"';
70
+ } ?>>
71
+ <td>
72
+ <!-- Title -->
73
+ <?php echo $addon->title ?>
74
+ </td>
75
+ <?php if ( $is_addon_connected ) : ?>
76
+ <!-- ID -->
77
+ <td><?php echo $site->id ?></td>
78
+ <!--/ ID -->
79
+
80
+ <!-- Version -->
81
+ <td><?php echo $fs_addon->get_plugin_version() ?></td>
82
+ <!--/ Version -->
83
+
84
+ <!-- Plan Title -->
85
+ <td><?php echo strtoupper( is_string( $plan->name ) ? $plan->title : $free_text ) ?></td>
86
+ <!--/ Plan Title -->
87
+
88
+ <?php if ( $fs_addon->is_trial() || is_object( $license ) ) : ?>
89
+
90
+ <!-- Expiration -->
91
+ <td>
92
+ <?php
93
+ $tags = array();
94
+
95
+ if ( $fs_addon->is_trial() ) {
96
+ $tags[] = array( 'label' => $trial_text, 'type' => 'success' );
97
+
98
+ $tags[] = array(
99
+ 'label' => sprintf(
100
+ ( $is_paid_trial ?
101
+ $renews_in_text :
102
+ $expires_in_text ),
103
+ human_time_diff( time(), strtotime( $site->trial_ends ) )
104
+ ),
105
+ 'type' => ( $is_paid_trial ? 'success' : 'warn' )
106
+ );
107
+ } else {
108
+ if ( is_object( $license ) ) {
109
+ if ( $license->is_cancelled ) {
110
+ $tags[] = array(
111
+ 'label' => fs_text_inline( 'Cancelled', 'cancelled', $slug ),
112
+ 'type' => 'error'
113
+ );
114
+ } else if ( $license->is_expired() ) {
115
+ $tags[] = array(
116
+ 'label' => fs_text_inline( 'Expired', 'expired', $slug ),
117
+ 'type' => 'error'
118
+ );
119
+ } else if ( $license->is_lifetime() ) {
120
+ $tags[] = array(
121
+ 'label' => fs_text_inline( 'No expiration', 'no-expiration', $slug ),
122
+ 'type' => 'success'
123
+ );
124
+ } else if ( ! $is_active_subscription && ! $license->is_first_payment_pending() ) {
125
+ $tags[] = array(
126
+ 'label' => sprintf( $expires_in_text, human_time_diff( time(), strtotime( $license->expiration ) ) ),
127
+ 'type' => 'warn'
128
+ );
129
+ } else if ( $is_active_subscription && ! $subscription->is_first_payment_pending() ) {
130
+ $tags[] = array(
131
+ 'label' => sprintf( $renews_in_text, human_time_diff( time(), strtotime( $subscription->next_payment ) ) ),
132
+ 'type' => 'success'
133
+ );
134
+ }
135
+ }
136
+ }
137
+
138
+ foreach ( $tags as $t ) {
139
+ printf( '<label class="fs-tag fs-%s">%s</label>' . "\n", $t['type'], $t['label'] );
140
+ }
141
+ ?>
142
+ </td>
143
+ <!--/ Expiration -->
144
+
145
+ <?php endif ?>
146
+
147
+ <?php
148
+ $buttons = array();
149
+ if ( $is_addon_activated ) {
150
+ if ( $is_paying ) {
151
+ $buttons[] = fs_ui_get_action_button(
152
+ $fs->get_id(),
153
+ 'account',
154
+ 'deactivate_license',
155
+ fs_text_inline( 'Deactivate License', 'deactivate-license', $slug ),
156
+ '',
157
+ array( 'plugin_id' => $addon_id ),
158
+ false
159
+ );
160
+
161
+ $human_readable_license_expiration = human_time_diff( time(), strtotime( $license->expiration ) );
162
+ $downgrade_confirmation_message = sprintf(
163
+ $downgrade_x_confirm_text,
164
+ $plan->title,
165
+ $human_readable_license_expiration
166
+ );
167
+
168
+ $after_downgrade_message = ! $license->is_block_features ?
169
+ sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs_addon->get_module_label( true ) ) :
170
+ sprintf( $after_downgrade_blocking_text, $plan->title );
171
+
172
+ if ( ! $license->is_lifetime() && $is_active_subscription ) {
173
+ $buttons[] = fs_ui_get_action_button(
174
+ $fs->get_id(),
175
+ 'account',
176
+ 'downgrade_account',
177
+ esc_html( $fs_addon->is_only_premium() ? fs_text_inline( 'Cancel Subscription', 'cancel-subscription', $slug ) : $downgrade_text ),
178
+ '',
179
+ array( 'plugin_id' => $addon_id ),
180
+ false,
181
+ false,
182
+ false,
183
+ ( $downgrade_confirmation_message . ' ' . $after_downgrade_message ),
184
+ 'POST'
185
+ );
186
+ }
187
+ } else if ( $is_paid_trial ) {
188
+ $buttons[] = fs_ui_get_action_button(
189
+ $fs->get_id(),
190
+ 'account',
191
+ 'cancel_trial',
192
+ esc_html( $cancel_trial_text ),
193
+ '',
194
+ array( 'plugin_id' => $addon_id ),
195
+ false,
196
+ false,
197
+ 'dashicons dashicons-download',
198
+ $cancel_trial_confirm_text,
199
+ 'POST'
200
+ );
201
+ } else {
202
+ $premium_license = $fs_addon->_get_available_premium_license();
203
+
204
+ if ( is_object( $premium_license ) ) {
205
+ $premium_plan = $fs_addon->_get_plan_by_id( $premium_license->plan_id );
206
+ $site = $fs_addon->get_site();
207
+
208
+ $buttons[] = fs_ui_get_action_button(
209
+ $fs->get_id(),
210
+ 'account',
211
+ 'activate_license',
212
+ esc_html( sprintf( $activate_plan_text, $premium_plan->title, ( $site->is_localhost() && $premium_license->is_free_localhost ) ? '[localhost]' : ( 1 < $premium_license->left() ? $premium_license->left() . ' left' : '' ) ) ),
213
+ '',
214
+ array(
215
+ 'plugin_id' => $addon_id,
216
+ 'license_id' => $premium_license->id,
217
+ )
218
+ );
219
+ }
220
+ }
221
+
222
+ if ( 0 == count( $buttons ) ) {
223
+ $fs_addon->_add_license_activation_dialog_box();
224
+
225
+ $buttons[] = fs_ui_get_action_button(
226
+ $fs->get_id(),
227
+ 'account',
228
+ 'activate_license',
229
+ fs_esc_html_inline( 'Activate License', 'activate-license', $slug ),
230
+ 'activate-license-trigger ' . $fs_addon->get_unique_affix(),
231
+ array(
232
+ 'plugin_id' => $addon_id,
233
+ ),
234
+ false,
235
+ true
236
+ );
237
+
238
+ // Add sync license only if non of the other CTAs are visible.
239
+ $buttons[] = fs_ui_get_action_button(
240
+ $fs->get_id(),
241
+ 'account',
242
+ $fs->get_unique_affix() . '_sync_license',
243
+ esc_html( $sync_license_text ),
244
+ '',
245
+ array( 'plugin_id' => $addon_id ),
246
+ false,
247
+ true
248
+ );
249
+
250
+ }
251
+ } else if ( ! $show_upgrade ) {
252
+ if ( $fs->is_addon_installed( $addon_id ) ) {
253
+ $addon_file = $fs->get_addon_basename( $addon_id );
254
+ $buttons[] = sprintf(
255
+ '<a class="button button-primary edit" href="%s" title="%s">%s</a>',
256
+ wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ),
257
+ fs_esc_attr_inline( 'Activate this add-on', 'activate-this-addon', $slug ),
258
+ $activate_text
259
+ );
260
+ } else {
261
+ if ( $fs->is_allowed_to_install() ) {
262
+ $buttons[] = sprintf(
263
+ '<a class="button button-primary edit" href="%s">%s</a>',
264
+ wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ),
265
+ fs_text_inline( 'Install Now', 'install-now', $slug )
266
+ );
267
+ } else {
268
+ $buttons[] = sprintf(
269
+ '<a target="_blank" class="button button-primary edit" href="%s">%s</a>',
270
+ $fs->_get_latest_download_local_url( $addon_id ),
271
+ esc_html( $download_latest_text )
272
+ );
273
+ }
274
+ }
275
+ }
276
+
277
+ if ( $show_upgrade ) {
278
+ $buttons[] = sprintf( '<a href="%s" class="thickbox button button-small button-primary" aria-label="%s" data-title="%s"><i class="dashicons dashicons-cart"></i> %s</a>',
279
+ esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&parent_plugin_id=' . $fs->get_id() . '&plugin=' . $addon->slug .
280
+ '&TB_iframe=true&width=600&height=550' ) ),
281
+ esc_attr( sprintf( fs_text_inline( 'More information about %s', 'more-information-about-x', $slug ), $addon->title ) ),
282
+ esc_attr( $addon->title ),
283
+ ( $fs_addon->has_free_plan() ?
284
+ $upgrade_text :
285
+ fs_text_x_inline( 'Purchase', 'verb', 'purchase', $slug ) )
286
+ );
287
+ }
288
+
289
+ $buttons_count = count( $buttons );
290
+ ?>
291
+
292
+ <!-- Actions -->
293
+ <td><?php if ( $buttons_count > 1 ) : ?>
294
+ <div class="button-group"><?php endif ?>
295
+ <?php foreach ( $buttons as $button ) {
296
+ echo $button;
297
+ } ?>
298
+ <?php if ( $buttons_count > 1 ) : ?></div><?php endif ?></td>
299
+ <!--/ Actions -->
300
+
301
+ <?php else : ?>
302
+ <?php // Add-on NOT Installed or was never connected.
303
+ ?>
304
+ <!-- Action -->
305
+ <td colspan="4">
306
+ <?php if ( $fs->is_addon_installed( $addon_id ) ) : ?>
307
+ <?php $addon_file = $fs->get_addon_basename( $addon_id ) ?>
308
+ <a class="button button-primary"
309
+ href="<?php echo wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $addon_file, 'activate-plugin_' . $addon_file ) ?>"
310
+ title="<?php fs_esc_attr_echo_inline( 'Activate this add-on', 'activate-this-addon', $slug ) ?>"
311
+ class="edit"><?php echo esc_html( $activate_text ) ?></a>
312
+ <?php else : ?>
313
+ <?php if ( $fs->is_allowed_to_install() ) : ?>
314
+ <a class="button button-primary"
315
+ href="<?php echo wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $addon->slug ), 'install-plugin_' . $addon->slug ) ?>"><?php fs_esc_html_echo_inline( 'Install Now', 'install-now', $slug ) ?></a>
316
+ <?php else : ?>
317
+ <a target="_blank" class="button button-primary"
318
+ href="<?php echo $fs->_get_latest_download_local_url( $addon_id ) ?>"><?php echo esc_html( $download_latest_text ) ?></a>
319
+ <?php endif ?>
320
+ <?php endif ?>
321
+ </td>
322
+ <!--/ Action -->
323
+ <?php endif ?>
324
+ <?php if ( ! $is_paying && WP_FS__DEV_MODE ) : ?>
325
+ <!-- Optional Delete Action -->
326
+ <td>
327
+ <?php
328
+ if ( $is_addon_activated ) {
329
+ fs_ui_action_button(
330
+ $fs->get_id(), 'account',
331
+ 'delete_account',
332
+ fs_text_x_inline( 'Delete', 'verb', 'delete', $slug ),
333
+ '',
334
+ array( 'plugin_id' => $addon_id ),
335
+ false,
336
+ $show_upgrade
337
+ );
338
+ }
339
+ ?>
340
+ </td>
341
+ <!--/ Optional Delete Action -->
342
+ <?php endif ?>
343
+ </tr>
sdk/freemius/templates/checkout.php CHANGED
@@ -303,6 +303,10 @@
303
  FS.PostMessage.post('context', <?php echo json_encode( $install_data ) ?>, frame[0]);
304
  });
305
 
 
 
 
 
306
  FS.PostMessage.receiveOnce('get_dimensions', function (data) {
307
  console.debug('receiveOnce', 'get_dimensions');
308
 
303
  FS.PostMessage.post('context', <?php echo json_encode( $install_data ) ?>, frame[0]);
304
  });
305
 
306
+ FS.PostMessage.receiveOnce('purchaseCompleted', <?php echo $fs->apply_filters('checkout/purchaseCompleted', 'function (data) {
307
+ console.log("checkout", "purchaseCompleted");
308
+ }') ?>);
309
+
310
  FS.PostMessage.receiveOnce('get_dimensions', function (data) {
311
  console.debug('receiveOnce', 'get_dimensions');
312
 
sdk/freemius/templates/debug.php CHANGED
@@ -394,7 +394,7 @@
394
  echo $plan_name;
395
  ?></td>
396
  <td><?php echo $site->public_key ?></td>
397
- <td><?php echo $site->secret_key ?></td>
398
  <td>
399
  <form action="" method="POST">
400
  <input type="hidden" name="fs_action" value="delete_install">
@@ -443,7 +443,7 @@
443
  <td><?php echo $addon->slug ?></td>
444
  <td><?php echo $addon->version ?></td>
445
  <td><?php echo $addon->public_key ?></td>
446
- <td><?php echo $addon->secret_key ?></td>
447
  </tr>
448
  <?php endforeach ?>
449
  </tbody>
@@ -477,7 +477,7 @@
477
  <td><a href="mailto:<?php echo esc_attr( $user->email ) ?>"><?php echo $user->email ?></a></td>
478
  <td><?php echo json_encode( $user->is_verified ) ?></td>
479
  <td><?php echo $user->public_key ?></td>
480
- <td><?php echo $user->secret_key ?></td>
481
  <td>
482
  <form action="" method="POST">
483
  <input type="hidden" name="fs_action" value="delete_user">
@@ -510,24 +510,18 @@
510
  </tr>
511
  </thead>
512
  <tbody>
513
- <?php foreach ( $licenses as $slug => $module_licenses ) : ?>
514
- <?php foreach ( $module_licenses as $id => $licenses ) : ?>
515
- <?php if ( is_array( $licenses ) && 0 < count( $licenses ) ) : ?>
516
- <?php foreach ( $licenses as $license ) : ?>
517
- <tr>
518
- <td><?php echo $license->id ?></td>
519
- <td><?php echo $license->plugin_id ?></td>
520
- <td><?php echo $license->user_id ?></td>
521
- <td><?php echo $license->plan_id ?></td>
522
- <td><?php echo $license->is_unlimited() ? 'Unlimited' : ( $license->is_single_site() ? 'Single Site' : $license->quota ) ?></td>
523
- <td><?php echo $license->activated ?></td>
524
- <td><?php echo $license->is_block_features ? 'Blocking' : 'Flexible' ?></td>
525
- <td><?php echo htmlentities( $license->secret_key ) ?></td>
526
- <td><?php echo $license->expiration ?></td>
527
- </tr>
528
- <?php endforeach ?>
529
- <?php endif ?>
530
- <?php endforeach ?>
531
  <?php endforeach ?>
532
  </tbody>
533
  </table>
394
  echo $plan_name;
395
  ?></td>
396
  <td><?php echo $site->public_key ?></td>
397
+ <td><?php echo esc_html( $site->secret_key ) ?></td>
398
  <td>
399
  <form action="" method="POST">
400
  <input type="hidden" name="fs_action" value="delete_install">
443
  <td><?php echo $addon->slug ?></td>
444
  <td><?php echo $addon->version ?></td>
445
  <td><?php echo $addon->public_key ?></td>
446
+ <td><?php echo esc_html( $addon->secret_key ) ?></td>
447
  </tr>
448
  <?php endforeach ?>
449
  </tbody>
477
  <td><a href="mailto:<?php echo esc_attr( $user->email ) ?>"><?php echo $user->email ?></a></td>
478
  <td><?php echo json_encode( $user->is_verified ) ?></td>
479
  <td><?php echo $user->public_key ?></td>
480
+ <td><?php echo esc_html( $user->secret_key ) ?></td>
481
  <td>
482
  <form action="" method="POST">
483
  <input type="hidden" name="fs_action" value="delete_user">
510
  </tr>
511
  </thead>
512
  <tbody>
513
+ <?php foreach ( $licenses as $license ) : ?>
514
+ <tr>
515
+ <td><?php echo $license->id ?></td>
516
+ <td><?php echo $license->plugin_id ?></td>
517
+ <td><?php echo $license->user_id ?></td>
518
+ <td><?php echo $license->plan_id ?></td>
519
+ <td><?php echo $license->is_unlimited() ? 'Unlimited' : ( $license->is_single_site() ? 'Single Site' : $license->quota ) ?></td>
520
+ <td><?php echo $license->activated ?></td>
521
+ <td><?php echo $license->is_block_features ? 'Blocking' : 'Flexible' ?></td>
522
+ <td><?php echo esc_html( $license->secret_key ) ?></td>
523
+ <td><?php echo $license->expiration ?></td>
524
+ </tr>
 
 
 
 
 
 
525
  <?php endforeach ?>
526
  </tbody>
527
  </table>
wp-security-audit-log.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin URI: http://www.wpsecurityauditlog.com/
5
  * Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  * Author: WP White Security
7
- * Version: 3.1.3
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpsecurityauditlog.com/
10
  * License: GPL2
@@ -54,7 +54,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
54
  *
55
  * @var string
56
  */
57
- public $version = '3.1.3';
58
 
59
  // Plugin constants.
60
  const PLG_CLS_PRFX = 'WSAL_';
4
  * Plugin URI: http://www.wpsecurityauditlog.com/
5
  * Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  * Author: WP White Security
7
+ * Version: 3.1.4
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpsecurityauditlog.com/
10
  * License: GPL2
54
  *
55
  * @var string
56
  */
57
+ public $version = '3.1.4';
58
 
59
  // Plugin constants.
60
  const PLG_CLS_PRFX = 'WSAL_';