This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,509 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.3
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$user = $fs->get_user();
$affiliate = $fs->get_affiliate();
$affiliate_terms = $fs->get_affiliate_terms();
$plugin_title = $fs->get_plugin_title();
$module_type = $fs->is_plugin() ?
WP_FS__MODULE_TYPE_PLUGIN :
WP_FS__MODULE_TYPE_THEME;
$commission = $affiliate_terms->get_formatted_commission();
$readonly = false;
$is_affiliate = is_object( $affiliate );
$is_pending_affiliate = false;
$email_address = ( is_object( $user ) ?
$user->email :
'' );
$full_name = ( is_object( $user ) ?
$user->get_name() :
'' );
$paypal_email_address = '';
$domain = '';
$extra_domains = array();
$promotion_method_social_media = false;
$promotion_method_mobile_apps = false;
$statistics_information = false;
$promotion_method_description = false;
$members_dashboard_login_url = 'https://members.freemius.com/login/';
$affiliate_application_data = $fs->get_affiliate_application_data();
if ( $is_affiliate && $affiliate->is_pending() ) {
$readonly = 'readonly';
$is_pending_affiliate = true;
$paypal_email_address = $affiliate->paypal_email;
$domain = $affiliate->domain;
$statistics_information = $affiliate_application_data['stats_description'];
$promotion_method_description = $affiliate_application_data['promotion_method_description'];
if ( ! empty( $affiliate_application_data['additional_domains'] ) ) {
$extra_domains = $affiliate_application_data['additional_domains'];
}
if ( ! empty( $affiliate_application_data['promotion_methods'] ) ) {
$promotion_methods = explode( ',', $affiliate_application_data['promotion_methods'] );
$promotion_method_social_media = in_array( 'social_media', $promotion_methods );
$promotion_method_mobile_apps = in_array( 'mobile_apps', $promotion_methods );
}
} else {
$current_user = Freemius::_get_current_wp_user();
$full_name = trim( $current_user->user_firstname . ' ' . $current_user->user_lastname );
$email_address = $current_user->user_email;
$domain = fs_strip_url_protocol( get_site_url() );
}
$affiliate_tracking = 30;
if ( is_object( $affiliate_terms ) ) {
$affiliate_tracking = ( ! is_null( $affiliate_terms->cookie_days ) ?
( $affiliate_terms->cookie_days . '-day' ) :
fs_text_inline( 'Non-expiring', 'non-expiring', $slug ) );
}
$apply_to_become_affiliate_text = fs_text_inline( 'Apply to become an affiliate', 'apply-to-become-an-affiliate', $slug );
$module_id = $fs->get_id();
$affiliate_program_terms_url = "https://freemius.com/plugin/{$module_id}/{$slug}/legal/affiliate-program/";
?>
<div id="fs_affiliation_content_wrapper" class="wrap">
<form method="post" action="">
<div id="poststuff">
<div class="postbox">
<div class="inside">
<div id="messages">
<div id="error_message" class="error" style="display: none">
<p><strong></strong></p>
</div>
<div id="message" class="updated" style="display: none">
<p><strong></strong></p>
</div>
<?php if ( $is_affiliate ) : ?>
<?php if ( $affiliate->is_active() ) : ?>
<div class="updated">
<p><strong><?php
echo sprintf(
fs_esc_html_inline( "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s.", 'affiliate-application-accepted', $slug ),
$plugin_title,
sprintf(
'<a href="%s" target="_blank" rel="noopener">%s</a>',
$members_dashboard_login_url,
$members_dashboard_login_url
)
);
?></strong></p>
</div>
<?php else : ?>
<?php
$message_text = '';
if ( $is_pending_affiliate ) {
$message_text = fs_text_inline( "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information.", 'affiliate-application-thank-you', $slug );
$message_container_class = 'updated';
} else if ( $affiliate->is_suspended() ) {
$message_text = fs_text_inline( 'Your affiliation account was temporarily suspended.', 'affiliate-account-suspended', $slug );
$message_container_class = 'notice notice-warning';
} else if ( $affiliate->is_rejected() ) {
$message_text = fs_text_inline( "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days.", 'affiliate-application-rejected', $slug );
$message_container_class = 'error';
} else if ( $affiliate->is_blocked() ) {
$message_text = fs_text_inline( 'Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support.', 'affiliate-account-blocked', $slug );
$message_container_class = 'error';
}
?>
<div class="<?php echo $message_container_class ?>">
<p><strong><?php echo esc_html( $message_text ) ?></strong></p>
</div>
<?php endif ?>
<?php endif ?>
</div>
<div class="entry-content">
<?php if ( ! $is_affiliate ) : ?>
<div id="application_messages_container">
<p><?php echo esc_html( sprintf( fs_text_inline( 'Like the %s? Become our ambassador and earn cash ;-)', 'become-an-ambassador', $slug ), $module_type ) ) ?></p>
<p><?php echo esc_html( sprintf( fs_text_inline( 'Refer new customers to our %s and earn %s commission on each successful sale you refer!', 'refer-new-customers', $slug ), $module_type, $commission ) ) ?></p>
</div>
<?php endif ?>
<h3><?php fs_esc_html_echo_inline( 'Program Summary', 'program-summary', $slug ) ?></h3>
<ul>
<li><?php echo esc_html( sprintf( fs_text_inline( '%s commission when a customer purchases a new license.', 'commission-on-new-license-purchase', $slug ), $commission ) ) ?></li>
<?php if ( is_object( $affiliate_terms ) && $affiliate_terms->has_renewals_commission() ) : ?>
<li><?php echo esc_html( sprintf( fs_text_inline( 'Get commission for automated subscription renewals.', 'renewals-commission', $slug ) ) ) ?></li>
<?php endif ?>
<?php if ( is_object( $affiliate_terms ) && ( ! $affiliate_terms->is_session_cookie() ) ) : ?>
<li><?php echo esc_html( sprintf( fs_text_inline( '%s tracking cookie after the first visit to maximize earnings potential.', 'affiliate-tracking', $slug ), $affiliate_tracking ) ) ?></li>
<?php endif ?>
<?php if ( is_object( $affiliate_terms ) && $affiliate_terms->has_lifetime_commission() ) : ?>
<li><?php fs_esc_html_echo_inline( 'Unlimited commissions.', 'unlimited-commissions', $slug ) ?></li>
<?php endif ?>
<li><?php echo esc_html( sprintf( fs_text_inline( '%s minimum payout amount.', 'minimum-payout-amount', $slug ), '$100' ) ) ?></li>
<li><?php fs_esc_html_echo_inline( 'Payouts are in USD and processed monthly via PayPal.', 'payouts-unit-and-processing', $slug ) ?></li>
<li><?php fs_esc_html_echo_inline( 'As we reserve 30 days for potential refunds, we only pay commissions that are older than 30 days.', 'commission-payment', $slug ) ?></li>
</ul>
<div id="application_form_container" <?php echo ( $is_pending_affiliate ) ? '' : 'style="display: none"' ?>>
<h3><?php fs_esc_html_echo_inline( 'Affiliate', 'affiliate', $slug ) ?></h3>
<form>
<div class="input-container input-container-text">
<label class="input-label"><?php fs_esc_html_echo_inline( 'Email address', 'email-address', $slug ) ?></label>
<input id="email_address" type="text" value="<?php echo esc_attr( $email_address ) ?>" class="regular-text" <?php echo ( $readonly || is_object( $user ) ) ? 'readonly' : '' ?>>
</div>
<div class="input-container input-container-text">
<label class="input-label"><?php fs_esc_html_echo_inline( 'Full name', 'full-name', $slug ) ?></label>
<input id="full_name" type="text" value="<?php echo esc_attr( $full_name ) ?>" class="regular-text" <?php echo $readonly ?>>
</div>
<div class="input-container input-container-text">
<label class="input-label"><?php fs_esc_html_echo_inline( 'PayPal account email address', 'paypal-account-email-address', $slug ) ?></label>
<input id="paypal_email" type="text" value="<?php echo esc_attr( $paypal_email_address ) ?>" class="regular-text" <?php echo $readonly ?>>
</div>
<div class="input-container input-container-text">
<label class="input-label"><?php echo esc_html( sprintf( fs_text_inline( 'Where are you going to promote the %s?', 'domain-field-label', $slug ), $module_type ) ) ?></label>
<input id="domain" type="text" value="<?php echo esc_attr( $domain ) ?>" class="domain regular-text" <?php echo $readonly ?>>
<p class="description"><?php echo esc_html( sprintf( fs_text_inline( 'Enter the domain of your website or other websites from where you plan to promote the %s.', 'domain-field-desc', $slug ), $module_type ) ) ?></p>
<?php if ( ! $is_affiliate ) : ?>
<a id="add_domain" href="#" class="disabled">+ <?php fs_esc_html_echo_inline( 'Add another domain', 'add-another-domain', $slug ) ?>...</a>
<?php endif ?>
</div>
<div id="extra_domains_container" class="input-container input-container-text" <?php echo $is_pending_affiliate ? '' : 'style="display: none"' ?>>
<label class="input-label"><?php fs_esc_html_echo_inline( 'Extra Domains', 'extra-domain-fields-label', $slug ) ?></label>
<p class="description"><?php fs_esc_html_echo_inline( 'Extra domains where you will be marketing the product from.', 'extra-domain-fields-desc', $slug ) ?></p>
<?php if ( $is_pending_affiliate && ! empty( $extra_domains ) ) : ?>
<?php foreach ( $extra_domains as $extra_domain ) : ?>
<div class="extra-domain-input-container">
<input type="text" value="<?php echo esc_attr( $extra_domain ) ?>" class="domain regular-text" <?php echo $readonly ?>>
</div>
<?php endforeach ?>
<?php endif ?>
</div>
<div class="input-container">
<label class="input-label"><?php fs_esc_html_echo_inline( 'Promotion methods', 'promotion-methods', $slug ) ?></label>
<div>
<input id="promotion_method_social_media" type="checkbox" <?php checked( $promotion_method_social_media ) ?> <?php disabled( $is_affiliate ) ?>/>
<label for="promotion_method_social_media"><?php fs_esc_html_echo_inline( 'Social media (Facebook, Twitter, etc.)', 'social-media', $slug ) ?></label>
</div>
<div>
<input id="promotion_method_mobile_apps" type="checkbox" <?php checked( $promotion_method_mobile_apps ) ?> <?php disabled( $is_affiliate ) ?>/>
<label for="promotion_method_mobile_apps"><?php fs_esc_html_echo_inline( 'Mobile apps', 'mobile-apps', $slug ) ?></label>
</div>
</div>
<div class="input-container input-container-text">
<label class="input-label"><nobr><?php fs_esc_html_echo_inline( 'Website, email, and social media statistics (optional)', 'statistics-information-field-label', $slug ) ?></nobr></label>
<textarea id="statistics_information" rows="5" <?php echo $readonly ?> class="regular-text"><?php echo $statistics_information ?></textarea>
<?php if ( ! $is_affiliate ) : ?>
<p class="description"><?php fs_esc_html_echo_inline( 'Please feel free to provide any relevant website or social media statistics, e.g. monthly unique site visits, number of email subscribers, followers, etc. (we will keep this information confidential).', 'statistics-information-field-desc', $slug ) ?></p>
<?php endif ?>
</div>
<div class="input-container input-container-text">
<label class="input-label"><?php fs_esc_html_echo_inline( 'How will you promote us?', 'promotion-method-desc-field-label', $slug ) ?></label>
<textarea id="promotion_method_description" rows="5" <?php echo $readonly ?> class="regular-text"><?php echo $promotion_method_description ?></textarea>
<?php if ( ! $is_affiliate ) : ?>
<p class="description"><?php echo esc_html( sprintf( fs_text_inline( 'Please provide details on how you intend to promote %s (please be as specific as possible).', 'promotion-method-desc-field-desc', $slug ), $plugin_title ) ) ?></p>
<?php endif ?>
</div>
<?php if ( ! $is_affiliate ) : ?>
<div>
<input type="checkbox" id="legal_consent_checkbox">
<label for="legal_consent_checkbox">I agree to the <a href="<?php echo $affiliate_program_terms_url ?>" target="_blank" rel="noopener">Referrer Program</a>'s terms & conditions.</label>
</div>
<?php endif ?>
</form>
</div>
<?php if ( ! $is_affiliate ) : ?>
<a id="cancel_button" href="#" class="button button-secondary button-cancel" style="display: none"><?php fs_esc_html_echo_inline( 'Cancel', 'cancel', $slug ) ?></a>
<a id="submit_button" class="button button-primary disabled" href="#" style="display: none"><?php echo esc_html( $apply_to_become_affiliate_text ) ?></a>
<a id="apply_button" class="button button-primary" href="#"><?php fs_esc_html_echo_inline( 'Become an affiliate', 'become-an-affiliate', $slug ) ?></a>
<?php endif ?>
</div>
</div>
</div>
</div>
</form>
<script type="text/javascript">
jQuery(function ($) {
var
$contentWrapper = $('#fs_affiliation_content_wrapper'),
$socialMedia = $('#promotion_method_social_media'),
$mobileApps = $('#promotion_method_mobile_apps'),
$applyButton = $('#apply_button'),
$submitButton = $('#submit_button'),
$cancelButton = $('#cancel_button'),
$applicationFormContainer = $('#application_form_container'),
$errorMessageContainer = $('#error_message'),
$domain = $('#domain'),
$addDomain = $('#add_domain'),
$extraDomainsContainer = $('#extra_domains_container'),
$legalConsentCheckbox = $( '#legal_consent_checkbox' );
$applyButton.click(function (evt) {
evt.preventDefault();
var $this = $(this);
$this.hide();
$applicationFormContainer.show();
$cancelButton.show();
$submitButton.show();
$contentWrapper.find('input[type="text"]:first').focus();
});
$submitButton.click(function (evt) {
evt.preventDefault();
var $this = $(this);
if ($this.hasClass('disabled')) {
return;
}
$errorMessageContainer.hide();
var
$emailAddress = $('#email_address'),
emailAddress = null,
paypalEmailAddress = $('#paypal_email').val().trim();
if (1 === $emailAddress.length) {
emailAddress = $emailAddress.val().trim();
if (0 === emailAddress.length) {
showErrorMessage('<?php fs_esc_js_echo_inline( 'Email address is required.', 'email-address-is-required', $slug ) ?>');
return;
}
}
if (0 === paypalEmailAddress.length) {
showErrorMessage('<?php fs_esc_js_echo_inline( 'PayPal email address is required.', 'paypal-email-address-is-required', $slug ) ?>');
return;
}
var
$extraDomains = $extraDomainsContainer.find('.domain'),
domain = $domain.val().trim().toLowerCase(),
extraDomains = [];
if (0 === domain.length) {
showErrorMessage('<?php fs_esc_js_echo_inline( 'Domain is required.', 'domain-is-required', $slug ) ?>');
return;
} else if ('freemius.com' === domain) {
showErrorMessage('<?php fs_esc_js_echo_inline( 'Invalid domain', 'invalid-domain', $slug ) ?>' + ' [' + domain + '].');
return;
}
if ($extraDomains.length > 0) {
var hasError = false;
$extraDomains.each(function () {
var
$this = $(this),
extraDomain = $this.val().trim().toLowerCase();
if (0 === extraDomain.length || extraDomain === domain) {
return true;
} else if ('freemius.com' === extraDomain) {
showErrorMessage('<?php fs_esc_js_echo_inline( 'Invalid domain', 'invalid-domain', $slug ) ?>' + ' [' + extraDomain + '].');
hasError = true;
return false;
}
extraDomains.push(extraDomain);
});
if (hasError) {
return;
}
}
var
promotionMethods = [],
statisticsInformation = $('#statistics_information').val(),
promotionMethodDescription = $('#promotion_method_description').val();
if ($socialMedia.attr('checked')) {
promotionMethods.push('social_media');
}
if ($mobileApps.attr('checked')) {
promotionMethods.push('mobile_apps');
}
var affiliate = {
full_name : $('#full_name').val().trim(),
paypal_email : paypalEmailAddress,
stats_description : statisticsInformation,
promotion_method_description: promotionMethodDescription
};
if (null !== emailAddress) {
affiliate.email = emailAddress;
}
affiliate.domain = domain;
affiliate.additional_domains = extraDomains;
if (promotionMethods.length > 0) {
affiliate.promotion_methods = promotionMethods.join(',');
}
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'submit_affiliate_application' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'submit_affiliate_application' ) ?>',
module_id: '<?php echo $module_id ?>',
affiliate: affiliate
},
beforeSend: function () {
$cancelButton.addClass('disabled');
$submitButton.addClass('disabled');
$submitButton.text('<?php fs_esc_js_echo_inline( 'Submitting', 'submitting' ) ?>...');
},
success : function (result) {
if (result.success) {
location.reload();
} else {
if (result.error && result.error.length > 0) {
showErrorMessage(result.error);
}
$cancelButton.removeClass('disabled');
$submitButton.removeClass('disabled');
$submitButton.text('<?php echo esc_js( $apply_to_become_affiliate_text ) ?>')
}
}
});
});
$cancelButton.click(function (evt) {
evt.preventDefault();
var $this = $(this);
if ($this.hasClass('disabled')) {
return;
}
$applicationFormContainer.hide();
$this.hide();
$submitButton.hide();
$applyButton.show();
window.scrollTo(0, 0);
});
$domain.on('input propertychange', onDomainChange);
$addDomain.click(function (evt) {
evt.preventDefault();
var
$this = $(this),
domain = $domain.val().trim();
if ($this.hasClass('disabled') || 0 === domain.length) {
return;
}
$domain.off('input propertychange');
$this.addClass('disabled');
var
$extraDomainInputContainer = $('<div class="extra-domain-input-container"><input type="text" class="domain regular-text"/></div>'),
$extraDomainInput = $extraDomainInputContainer.find('input'),
$removeDomain = $('<a href="#" class="remove-domain"><i class="dashicons dashicons-no" title="<?php fs_esc_js_echo_inline( 'Remove', 'remove', $slug ) ?>"></i></a>');
$extraDomainInputContainer.append($removeDomain);
$extraDomainInput.on('input propertychange', onDomainChange);
$removeDomain.click(function (evt) {
evt.preventDefault();
var
$extraDomainInputs = $('.extra-domain-input-container .domain');
if (1 === $extraDomainInputs.length)
$extraDomainInputs.val('').focus();
else
$(this).parent().remove();
});
$extraDomainsContainer.show();
$extraDomainInputContainer.appendTo($extraDomainsContainer);
$extraDomainInput.focus();
$this.appendTo($extraDomainsContainer);
});
/**
* @author Leo Fajardo (@leorw)
*/
function onDomainChange() {
var
domain = $(this).val().trim();
if (domain.length > 0) {
$addDomain.removeClass('disabled');
} else {
$addDomain.addClass('disabled');
}
}
/**
* @author Leo Fajardo (@leorw)
*
* @param {String} message
*/
function showErrorMessage(message) {
$errorMessageContainer.find('strong').text(message);
$errorMessageContainer.show();
window.scrollTo(0, 0);
}
/**
* @author Xiaheng Chen (@xhchen)
*
* @since 2.4.0
*/
$legalConsentCheckbox.click( function () {
if ( $( this ).prop( 'checked' ) ) {
$submitButton.removeClass( 'disabled' );
} else {
$submitButton.addClass( 'disabled' );
}
} );
});
</script>
</div>
<?php
$params = array(
'page' => 'affiliation',
'module_id' => $module_id,
'module_slug' => $slug,
'module_version' => $fs->get_plugin_version(),
);
fs_require_template( 'powered-by.php', $params );
?>

View File

@ -0,0 +1,23 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug )
. sprintf(" <a href='%s' class='button button-small button-primary'>%s</a>",
$fs->contact_url( 'technical_support' ),
fs_text_inline( 'Contact Support', 'contact-support', $slug )
);

View File

@ -0,0 +1,543 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.1.2
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$subscription_cancellation_dialog_box_template_params = $VARS['subscription_cancellation_dialog_box_template_params'];
$show_deactivation_feedback_form = $VARS['show_deactivation_feedback_form'];
$confirmation_message = $VARS['uninstall_confirmation_message'];
$is_anonymous = ( ! $fs->is_registered() );
$anonymous_feedback_checkbox_html = '';
$reasons_list_items_html = '';
if ( $show_deactivation_feedback_form ) {
$reasons = $VARS['reasons'];
foreach ( $reasons as $reason ) {
$list_item_classes = 'reason' . ( ! empty( $reason['input_type'] ) ? ' has-input' : '' );
if ( isset( $reason['internal_message'] ) && ! empty( $reason['internal_message'] ) ) {
$list_item_classes .= ' has-internal-message';
$reason_internal_message = $reason['internal_message'];
} else {
$reason_internal_message = '';
}
$reason_input_type = ( ! empty( $reason['input_type'] ) ? $reason['input_type'] : '' );
$reason_input_placeholder = ( ! empty( $reason['input_placeholder'] ) ? $reason['input_placeholder'] : '' );
$reason_list_item_html = <<< HTML
<li class="{$list_item_classes}"
data-input-type="{$reason_input_type}"
data-input-placeholder="{$reason_input_placeholder}">
<label>
<span>
<input type="radio" name="selected-reason" value="{$reason['id']}"/>
</span>
<span>{$reason['text']}</span>
</label>
<div class="internal-message">{$reason_internal_message}</div>
</li>
HTML;
$reasons_list_items_html .= $reason_list_item_html;
}
if ( $is_anonymous ) {
$anonymous_feedback_checkbox_html = sprintf(
'<label class="anonymous-feedback-label"><input type="checkbox" class="anonymous-feedback-checkbox"> %s</label>',
fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug )
);
}
}
// Aliases.
$deactivate_text = fs_text_inline( 'Deactivate', 'deactivate', $slug );
$theme_text = fs_text_inline( 'Theme', 'theme', $slug );
$activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug );
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
if ( ! empty( $subscription_cancellation_dialog_box_template_params ) ) {
fs_require_template( 'forms/subscription-cancellation.php', $subscription_cancellation_dialog_box_template_params );
}
?>
<script type="text/javascript">
(function ($) {
var reasonsHtml = <?php echo json_encode( $reasons_list_items_html ) ?>,
modalHtml =
'<div class="fs-modal fs-modal-deactivation-feedback<?php echo empty( $confirmation_message ) ? ' no-confirmation-message' : ''; ?>">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php fs_esc_attr_echo_inline( 'Quick Feedback', 'quick-feedback' , $slug ) ?></h4>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel" data-panel-id="confirm"><p><?php echo $confirmation_message; ?></p></div>'
+ ' <div class="fs-modal-panel active" data-panel-id="reasons"><h3><strong><?php echo esc_js( sprintf( fs_text_inline( 'If you have a moment, please let us know why you are %s', 'deactivation-share-reason' , $slug ), ( $fs->is_plugin() ? fs_text_inline( 'deactivating', 'deactivating', $slug ) : fs_text_inline( 'switching', 'switching', $slug ) ) ) ) ?>:</strong></h3><ul id="reasons-list">' + reasonsHtml + '</ul></div>'
+ ' </div>'
+ ' <div class="fs-modal-footer">'
+ ' <?php echo $anonymous_feedback_checkbox_html ?>'
+ ' <a href="#" class="button button-secondary button-deactivate"></a>'
+ ' <a href="#" class="button button-secondary button-close"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></a>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $(modalHtml),
selectedReasonID = false,
redirectLink = '',
$anonymousFeedback = $modal.find( '.anonymous-feedback-label' ),
isAnonymous = <?php echo ( $is_anonymous ? 'true' : 'false' ); ?>,
otherReasonID = <?php echo Freemius::REASON_OTHER; ?>,
dontShareDataReasonID = <?php echo Freemius::REASON_DONT_LIKE_TO_SHARE_MY_INFORMATION; ?>,
deleteThemeUpdateData = <?php echo $fs->is_theme() && $fs->is_premium() && ! $fs->has_any_active_valid_license() ? 'true' : 'false' ?>,
$subscriptionCancellationModal = $( '.fs-modal-subscription-cancellation-<?php echo $fs->get_id() ?>' ),
showDeactivationFeedbackForm = <?php echo ( $show_deactivation_feedback_form ? 'true' : 'false' ) ?>,
$body = $( 'body' );
$modal.appendTo( $body );
if ( 0 !== $subscriptionCancellationModal.length ) {
$subscriptionCancellationModal.on( '<?php echo $fs->get_action_tag( 'subscription_cancellation_action' ) ?>', function( evt, cancelSubscription ) {
var shouldDeactivateModule = ( $modal.hasClass( 'no-confirmation-message' ) && ! showDeactivationFeedbackForm );
if ( false === cancelSubscription ) {
if ( ! shouldDeactivateModule ) {
showModal();
}
$subscriptionCancellationModal.trigger( 'closeModal' );
if ( shouldDeactivateModule ) {
deactivateModule();
}
} else {
var $errorMessage = $subscriptionCancellationModal.find( '.notice-error' );
<?php
$subscription_cancellation_context = $fs->is_paid_trial() ?
fs_text_inline( 'trial', 'trial', $slug ) :
fs_text_inline( 'subscription', 'subscription', $slug );
?>
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'cancel_subscription_or_trial' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'cancel_subscription_or_trial' ) ?>',
module_id: '<?php echo $fs->get_id() ?>'
},
beforeSend: function() {
$errorMessage.hide();
$subscriptionCancellationModal.find( '.fs-modal-footer .button' ).addClass( 'disabled' );
$subscriptionCancellationModal.find( '.fs-modal-footer .button-primary' ).text( '<?php echo esc_js(
sprintf( fs_text_inline( 'Cancelling %s...', 'cancelling-x' , $slug ), $subscription_cancellation_context )
) ?>' );
},
success: function( result ) {
if ( result.success ) {
$subscriptionCancellationModal.removeClass( 'has-subscription-actions' );
$subscriptionCancellationModal.find( '.fs-modal-footer .button-primary' ).removeClass( 'warn' );
$subscriptionCancellationModal.remove();
if ( ! shouldDeactivateModule ) {
showModal();
} else {
deactivateModule();
}
} else {
$errorMessage.find( '> p' ).html( result.error );
$errorMessage.show();
$subscriptionCancellationModal.find( '.fs-modal-footer .button' ).removeClass( 'disabled' );
$subscriptionCancellationModal.find( '.fs-modal-footer .button-primary' ).html( <?php echo json_encode( sprintf(
fs_text_inline( 'Cancel %s & Proceed', 'cancel-x-and-proceed', $slug ),
ucfirst( $subscription_cancellation_context )
) ) ?> );
}
}
});
}
});
}
registerEventHandlers();
function registerEventHandlers() {
$body.on( 'click', '#the-list .deactivate > a', function ( evt ) {
if ( 0 === $( this ).next( '[data-module-id=<?php echo $fs->get_id() ?>].fs-module-id' ).length ) {
return true;
}
evt.preventDefault();
redirectLink = $(this).attr('href');
if ( 0 == $subscriptionCancellationModal.length ) {
showModal();
} else {
$subscriptionCancellationModal.trigger( 'showModal' );
}
});
<?php
if ( ! $fs->is_plugin() ) {
/**
* For "theme" module type, the modal is shown when the current user clicks on
* the "Activate" button of any other theme. The "Activate" button is actually
* a link to the "Themes" page (/wp-admin/themes.php) containing query params
* that tell WordPress to deactivate the current theme and activate a different theme.
*
* @author Leo Fajardo (@leorw)
* @since 1.2.2
*
* @since 1.2.2.7 Don't trigger the deactivation feedback form if activating the premium version of the theme.
*/
?>
$('body').on('click', '.theme-browser .theme:not([data-slug=<?php echo $fs->get_premium_slug() ?>]) .theme-actions .button.activate', function (evt) {
evt.preventDefault();
redirectLink = $(this).attr('href');
if ( 0 != $subscriptionCancellationModal.length ) {
$subscriptionCancellationModal.trigger( 'showModal' );
} else {
if ( $modal.hasClass( 'no-confirmation-message' ) && ! showDeactivationFeedbackForm ) {
deactivateModule();
} else {
showModal();
}
}
});
<?php
} ?>
$modal.on('input propertychange', '.reason-input input', function () {
if (!isOtherReasonSelected()) {
return;
}
var reason = $(this).val().trim();
/**
* If reason is not empty, remove the error-message class of the message container
* to change the message color back to default.
*/
if (reason.length > 0) {
$('.message').removeClass('error-message');
enableDeactivateButton();
}
});
$modal.on('blur', '.reason-input input', function () {
var $userReason = $(this);
setTimeout(function () {
if (!isOtherReasonSelected()) {
return;
}
/**
* If reason is empty, add the error-message class to the message container
* to change the message color to red.
*/
if (0 === $userReason.val().trim().length) {
$('.message').addClass('error-message');
disableDeactivateButton();
}
}, 150);
});
$modal.on('click', '.fs-modal-footer .button', function (evt) {
evt.preventDefault();
if ($(this).hasClass('disabled')) {
return;
}
var _parent = $(this).parents('.fs-modal:first');
var _this = $(this);
if (_this.hasClass('allow-deactivate')) {
var $radio = $modal.find('input[type="radio"]:checked');
if (0 === $radio.length) {
if ( ! deleteThemeUpdateData ) {
// If no selected reason, just deactivate the plugin.
window.location.href = redirectLink;
} else {
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'delete_theme_update_data' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'delete_theme_update_data' ) ?>',
module_id: '<?php echo $fs->get_id() ?>'
},
beforeSend: function() {
_parent.find( '.fs-modal-footer .button' ).addClass( 'disabled' );
_parent.find( '.fs-modal-footer .button-secondary' ).text( 'Processing...' );
},
complete : function() {
window.location.href = redirectLink;
}
});
}
return;
}
var $selected_reason = $radio.parents('li:first'),
$input = $selected_reason.find('textarea, input[type="text"]'),
userReason = ( 0 !== $input.length ) ? $input.val().trim() : '';
if (isOtherReasonSelected() && ( '' === userReason )) {
return;
}
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'submit_uninstall_reason' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'submit_uninstall_reason' ) ?>',
module_id : '<?php echo $fs->get_id() ?>',
reason_id : $radio.val(),
reason_info : userReason,
is_anonymous: isAnonymousFeedback()
},
beforeSend: function () {
_parent.find('.fs-modal-footer .button').addClass('disabled');
_parent.find('.fs-modal-footer .button-secondary').text('Processing...');
},
complete : function () {
// Do not show the dialog box, deactivate the plugin.
window.location.href = redirectLink;
}
});
} else if (_this.hasClass('button-deactivate')) {
// Change the Deactivate button's text and show the reasons panel.
_parent.find('.button-deactivate').addClass('allow-deactivate');
if ( showDeactivationFeedbackForm ) {
showPanel('reasons');
} else {
deactivateModule();
}
}
});
$modal.on('click', 'input[type="radio"]', function () {
var $selectedReasonOption = $( this );
// If the selection has not changed, do not proceed.
if (selectedReasonID === $selectedReasonOption.val())
return;
selectedReasonID = $selectedReasonOption.val();
if ( isAnonymous ) {
if ( isReasonSelected( dontShareDataReasonID ) ) {
$anonymousFeedback.hide();
} else {
$anonymousFeedback.show();
}
}
var _parent = $(this).parents('li:first');
$modal.find('.reason-input').remove();
$modal.find( '.internal-message' ).hide();
$modal.find('.button-deactivate').html('<?php echo esc_js( sprintf(
fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit' , $slug ),
$fs->is_plugin() ?
$deactivate_text :
sprintf( $activate_x_text, $theme_text )
) ) ?>');
enableDeactivateButton();
if ( _parent.hasClass( 'has-internal-message' ) ) {
_parent.find( '.internal-message' ).show();
}
if (_parent.hasClass('has-input')) {
var inputType = _parent.data('input-type'),
inputPlaceholder = _parent.data('input-placeholder'),
reasonInputHtml = '<div class="reason-input"><span class="message"></span>' + ( ( 'textfield' === inputType ) ? '<input type="text" maxlength="128" />' : '<textarea rows="5" maxlength="128"></textarea>' ) + '</div>';
_parent.append($(reasonInputHtml));
_parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
if (isOtherReasonSelected()) {
showMessage('<?php echo esc_js( fs_text_inline( 'Kindly tell us the reason so we can improve.', 'ask-for-reason-message' , $slug ) ); ?>');
disableDeactivateButton();
}
}
});
// If the user has clicked outside the window, cancel it.
$modal.on('click', function (evt) {
var $target = $(evt.target);
// If the user has clicked anywhere in the modal dialog, just return.
if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
return;
}
// If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
if (
! $target.hasClass( 'button-close' ) &&
( $target.parents( '.fs-modal-body' ).length > 0 || $target.parents( '.fs-modal-footer' ).length > 0 )
) {
return;
}
closeModal();
return false;
});
}
function isAnonymousFeedback() {
if ( ! isAnonymous ) {
return false;
}
return ( isReasonSelected( dontShareDataReasonID ) || $anonymousFeedback.find( 'input' ).prop( 'checked' ) );
}
function isReasonSelected( reasonID ) {
// Get the selected radio input element.
var $selectedReasonOption = $modal.find('input[type="radio"]:checked');
return ( reasonID == $selectedReasonOption.val() );
}
function isOtherReasonSelected() {
return isReasonSelected( otherReasonID );
}
function showModal() {
resetModal();
// Display the dialog box.
$modal.addClass('active');
$('body').addClass('has-fs-modal');
}
function closeModal() {
$modal.removeClass('active');
$('body').removeClass('has-fs-modal');
}
function resetModal() {
selectedReasonID = false;
enableDeactivateButton();
// Uncheck all radio buttons.
$modal.find('input[type="radio"]').prop('checked', false);
// Remove all input fields ( textfield, textarea ).
$modal.find('.reason-input').remove();
$modal.find('.message').hide();
if ( isAnonymous ) {
$anonymousFeedback.find( 'input' ).prop( 'checked', false );
// Hide, since by default there is no selected reason.
$anonymousFeedback.hide();
}
var $deactivateButton = $modal.find('.button-deactivate');
/*
* If the modal dialog has no confirmation message, that is, it has only one panel, then ensure
* that clicking the deactivate button will actually deactivate the plugin.
*/
if ( $modal.hasClass( 'no-confirmation-message' ) ) {
$deactivateButton.addClass( 'allow-deactivate' );
showPanel( 'reasons' );
} else {
$deactivateButton.removeClass( 'allow-deactivate' );
showPanel( 'confirm' );
}
}
function showMessage(message) {
$modal.find('.message').text(message).show();
}
function enableDeactivateButton() {
$modal.find('.button-deactivate').removeClass('disabled');
}
function disableDeactivateButton() {
$modal.find('.button-deactivate').addClass('disabled');
}
function showPanel(panelType) {
$modal.find( '.fs-modal-panel' ).removeClass( 'active' );
$modal.find( '[data-panel-id="' + panelType + '"]' ).addClass( 'active' );
updateButtonLabels();
}
function updateButtonLabels() {
var $deactivateButton = $modal.find( '.button-deactivate' );
// Reset the deactivate button's text.
if ( 'confirm' === getCurrentPanel() ) {
$deactivateButton.text( <?php echo json_encode( sprintf(
fs_text_inline( 'Yes - %s', 'deactivation-modal-button-confirm', $slug ),
$fs->is_plugin() ?
$deactivate_text :
sprintf( $activate_x_text, $theme_text )
) ) ?> );
} else {
$deactivateButton.html( <?php echo json_encode( sprintf(
fs_text_inline('Skip & %s', 'skip-and-x', $slug ),
$fs->is_plugin() ?
$deactivate_text :
sprintf( $activate_x_text, $theme_text )
) ) ?> );
}
}
function getCurrentPanel() {
return $modal.find('.fs-modal-panel.active').attr('data-panel-id');
}
/**
* @author Leo Fajardo (@leorw)
*
* @since 2.3.0
*/
function deactivateModule() {
window.location.href = redirectLink;
}
})(jQuery);
</script>

View File

@ -0,0 +1,3 @@
<?php
// Silence is golden.
// Hide file structure from users on unprotected servers.

View File

@ -0,0 +1,24 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' );
$skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) );
$use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug );
echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "<a href='{$skip_url}'>{$skip_text}</a>" )
. " <a href='{$skip_url}' class='button button-small button-secondary'>{$use_plugin_anonymously_text}</a>";

View File

@ -0,0 +1,3 @@
<?php
// Silence is golden.
// Hide file structure from users on unprotected servers.

View File

@ -0,0 +1,870 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.1.9
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
*
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$unique_affix = $fs->get_unique_affix();
$cant_find_license_key_text = fs_text_inline( "Can't find your license key?", 'cant-find-license-key', $slug );
$message_above_input_field = fs_text_inline( 'Please enter the license key that you received in the email right after the purchase:', 'activate-license-message', $slug );
$message_below_input_field = '';
$header_title = $fs->is_free_plan() ?
fs_text_inline( 'Activate License', 'activate-license', $slug ) :
fs_text_inline( 'Update License', 'update-license', $slug );
if ( $fs->is_registered() ) {
$activate_button_text = $header_title;
} else {
$freemius_site_url = $fs->has_paid_plan() ?
'https://freemius.com/' :
// Insights platform information.
$fs->get_usage_tracking_terms_url();
$freemius_link = '<a href="' . $freemius_site_url . '" target="_blank" rel="noopener" tabindex="0">freemius.com</a>';
$message_below_input_field = sprintf(
fs_text_inline( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ),
$fs->get_module_label( true ),
$freemius_link
);
$activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug );
}
$license_key_text = fs_text_inline( 'License key', 'license-key' , $slug );
$is_network_activation = (
$fs->is_network_active() &&
fs_is_network_admin() &&
! $fs->is_delegated_connection()
);
$network_activation_html = '';
$sites_details = array();
if ( $is_network_activation ) {
$all_sites = Freemius::get_sites();
foreach ( $all_sites as $site ) {
$site_details = $fs->get_site_info( $site );
$blog_id = Freemius::get_site_blog_id( $site );
$install = $fs->get_install_by_blog_id($blog_id);
if ( is_object( $install ) && FS_Plugin_License::is_valid_id( $install->license_id ) ) {
$site_details['license_id'] = $install->license_id;
}
$sites_details[] = $site_details;
}
if ( $is_network_activation ) {
$vars = array(
'id' => $fs->get_id(),
'sites' => $sites_details,
'require_license_key' => true
);
$network_activation_html = fs_get_template( 'partials/network-activation.php', $vars );
}
}
$premium_licenses = $fs->get_available_premium_licenses();
$available_licenses = array();
foreach ( $premium_licenses as $premium_license ) {
$activations_left = $premium_license->left();
if ( ! ( $activations_left > 0 ) ) {
continue;
}
$available_licenses[ $activations_left . '_' . $premium_license->id ] = $premium_license;
}
$total_available_licenses = count( $available_licenses );
if ( $total_available_licenses > 0 ) {
$license_input_html = <<< HTML
<div class="fs-license-options-container">
<table>
<tbody>
<tr class="fs-available-license-key-container">
<td><input type="radio" name="license_type" value="available"></td>
<td>
HTML;
if ( $total_available_licenses > 1 ) {
// Sort the licenses by number of activations left in descending order.
krsort( $available_licenses );
$license_input_html .= '<select class="fs-licenses">';
/**
* @var FS_Plugin_License $license
*/
foreach ( $available_licenses as $license ) {
$plan = $fs->_get_plan_by_id( $license->plan_id );
$label = sprintf(
"%s-Site %s License - %s",
( 1 == $license->quota ?
'Single' :
( $license->is_unlimited() ? 'Unlimited' : $license->quota )
),
( is_object( $plan ) ? $plan->title : '' ),
$license->get_html_escaped_masked_secret_key()
);
$license_input_html .= "<option data-id='{$license->id}' value='{$license->secret_key}' data-left='{$license->left()}'>{$label}</option>";
}
$license_input_html .= '</select>';
} else {
$available_licenses = array_values( $available_licenses );
/**
* @var FS_Plugin_License $available_license
*/
$available_license = $available_licenses[0];
$value = sprintf(
"%s-Site %s License - %s",
( 1 == $available_license->quota ?
'Single' :
( $available_license->is_unlimited() ? 'Unlimited' : $available_license->quota )
),
$fs->_get_plan_by_id( $available_license->plan_id )->title,
$available_license->get_html_escaped_masked_secret_key()
);
$license_input_html .= <<< HTML
<input
class="fs-available-license-key"
type="text"
value="{$value}"
data-id="{$available_license->id}"
data-license-key="{$available_license->secret_key}"
data-left="{$available_license->left()}"
readonly />
HTML;
}
$license_input_html .= <<< HTML
</td>
</tr>
<tr>
<td><input type="radio" name="license_type" value="other"></td>
<td class="fs-other-license-key-container">
<label for="other_license_key_{$unique_affix}">Other: </label>
<div>
<input id="other_license_key_{$unique_affix}" class="fs-license-key" type="text" placeholder="Enter license key" tabindex="1">
</div>
</td>
</tr>
</tbody>
</table>
</div>
HTML;
} else {
$license_input_html = "<input class='fs-license-key' type='text' placeholder='{$license_key_text}' tabindex='1' />";
}
$ownership_change_option_text = fs_text_inline( "Associate with the license owner's account.", 'associate-account-with-license-owner', $slug );
$ownership_change_option_html = "<div class='ownership-change-option-container' style='display: none'><label><input type='checkbox' /> <strong>{$ownership_change_option_text}</strong></label></div>";
/**
* IMPORTANT:
* DO NOT ADD MAXLENGTH OR LIMIT THE LICENSE KEY LENGTH SINCE
* WE DO WANT TO ALLOW INPUT OF LONGER KEYS (E.G. WooCommerce Keys)
* FOR MIGRATED MODULES.
*/
$modal_content_html = <<< HTML
<div class="notice notice-error inline license-activation-message"><p></p></div>
<p>{$message_above_input_field}</p>
{$license_input_html}
<a class="show-license-resend-modal show-license-resend-modal-{$fs->get_unique_affix()}" href="!#" tabindex="2">{$cant_find_license_key_text}</a>
{$network_activation_html}
<p>{$message_below_input_field}</p>
{$ownership_change_option_html}
HTML;
/**
* Handle the ownership change option if not an add-on or if no license yet is activated for the
* parent product in case of an add-on.
*
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
$is_user_change_supported = ( ! $fs->is_addon() || ! $fs->get_parent_instance()->has_active_valid_license() );
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
?>
<script type="text/javascript">
(function( $ ) {
$( document ).ready(function() {
var modalContentHtml = <?php echo json_encode($modal_content_html); ?>,
modalHtml =
'<div class="fs-modal fs-modal-license-activation fs-modal-license-activation-<?php echo $unique_affix ?>">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_js($header_title) ?></h4>'
+ ' <a href="!#" class="fs-close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss', $slug ) ) ?>"></i></a>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
+ ' </div>'
+ ' <div class="fs-modal-footer">'
+ ' <button class="button button-secondary button-close" tabindex="4"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></button>'
+ ' <button class="button button-primary button-activate-license" tabindex="3"><?php echo esc_js( $activate_button_text ) ?></button>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $(modalHtml),
$activateLicenseButton = $modal.find('.button-activate-license'),
$licenseKeyInput = $modal.find( 'input.fs-license-key' ),
$licenseActivationMessage = $modal.find( '.license-activation-message' ),
isNetworkActivation = <?php echo $is_network_activation ? 'true' : 'false' ?>,
isUserChangeSupported = <?php echo $is_user_change_supported ? 'true' : 'false' ?>,
isSingleSiteActivation = false,
$ownershipChangeOptionContainer = $modal.find( '.ownership-change-option-container' ),
$body = $( 'body' );
$modal.appendTo( $body );
var
$licensesDropdown = $modal.find( '.fs-licenses' ),
$licenseTypes = $modal.find( 'input[type="radio"][name="license_type"]' ),
$applyOnAllSites = $modal.find( '.fs-apply-on-all-sites-checkbox' ),
$sitesListContainer = $modal.find( '.fs-sites-list-container' ),
$availableLicenseKey = $modal.find( '.fs-available-license-key' ),
$otherLicenseKey = $modal.find( '#other_license_key_<?php echo $unique_affix ?>' ),
$multisiteOptionsContainer = $modal.find( '.fs-multisite-options-container' ),
$activationsLeft = null,
hasLicensesDropdown = ( $licensesDropdown.length > 0 ),
hasLicenseTypes = ( $licenseTypes.length > 0 ),
maxSitesListHeight = null,
totalSites = <?php echo count( $sites_details ) ?>,
singleBlogID = null;
var
previousLicenseKey = null,
otherLicenseOwnerID = null,
/**
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
resetLoadingMode = function () {
// Reset loading mode.
$activateLicenseButton.text( <?php echo json_encode( $activate_button_text ) ?> );
$activateLicenseButton.prop( 'disabled', false );
$( document.body ).css( { 'cursor': 'auto' } );
$( '.fs-loading' ).removeClass( 'fs-loading' );
console.log( 'resetLoadingMode - Primary button was enabled' );
},
/**
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
setLoadingMode = function () {
$( document.body ).css( { 'cursor': 'wait' } );
},
/**
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
afterLicenseUserDataLoaded = function () {
if (
null !== otherLicenseOwnerID &&
otherLicenseOwnerID != <?php echo $fs->is_registered() ? $fs->get_user()->id : 'null' ?>
) {
$ownershipChangeOptionContainer.show();
} else {
$ownershipChangeOptionContainer.hide();
$activateLicenseButton.focus();
}
},
/**
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
fetchLicenseUserData = function () {
var hideAndUncheckUserChangeCheckbox = ( ! isUserChangeSupported ),
otherLicenseKeyIsSelected = isOtherLicenseKeySelected();
if ( ! hideAndUncheckUserChangeCheckbox ) {
// User change is supported only on the site level.
hideAndUncheckUserChangeCheckbox = ( isNetworkActivation || isSingleSiteActivation );
}
if ( ! hideAndUncheckUserChangeCheckbox ) {
hideAndUncheckUserChangeCheckbox = ( hasLicenseTypes && ! otherLicenseKeyIsSelected );
}
var licenseKey = $licenseKeyInput.val().trim();
if ( ! hideAndUncheckUserChangeCheckbox && otherLicenseKeyIsSelected ) {
hideAndUncheckUserChangeCheckbox = ( licenseKey.length < 32 );
}
if ( licenseKey !== previousLicenseKey ) {
// If the license key has not been changed, keep the owner ID in order to prevent another API call.
otherLicenseOwnerID = null;
}
if ( hideAndUncheckUserChangeCheckbox ) {
$ownershipChangeOptionContainer.hide().find( 'input' ).attr( 'checked', false );
return;
}
if ( null !== otherLicenseOwnerID ) {
afterLicenseUserDataLoaded();
return;
}
setLoadingMode();
$activateLicenseButton.addClass( 'fs-loading' );
$activateLicenseButton.attr( 'disabled', 'disabled' );
$activateLicenseButton.html( '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...' );
$.ajax( {
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'fetch_is_marketing_required_flag_value' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'fetch_is_marketing_required_flag_value' ) ?>',
license_key: licenseKey,
module_id : '<?php echo $fs->get_id() ?>'
},
success: function ( result ) {
resetLoadingMode();
if ( result.success ) {
result = result.data;
// Cache license owner's ID.
otherLicenseOwnerID = result.license_owner_id;
}
afterLicenseUserDataLoaded();
}
} );
};
function registerEventHandlers() {
var
$otherLicenseKeyContainer = $modal.find( '.fs-other-license-key-container' );
if ( isNetworkActivation ) {
$applyOnAllSites.click(function() {
var applyOnAllSites = $( this ).is( ':checked' );
$multisiteOptionsContainer.toggleClass( 'fs-apply-on-all-sites', applyOnAllSites );
showSites( ! applyOnAllSites );
if ( hasValidLicenseKey() && ( applyOnAllSites || hasSelectedSite() ) ) {
enableActivateLicenseButton();
} else {
disableActivateLicenseButton();
}
});
$sitesListContainer.delegate( 'td:not(:first-child)', 'click', function() {
// If a site row is clicked, trigger a click on the checkbox.
$( this ).parent().find( 'td:first-child input' ).click();
});
$sitesListContainer.delegate( 'input[type="checkbox"]', 'click', function() {
enableDisableSitesSelection();
if ( hasValidLicenseKey() && hasSelectedSite() ) {
enableActivateLicenseButton();
} else {
disableActivateLicenseButton();
}
});
}
if ( hasLicensesDropdown ) {
$licensesDropdown.change(function() {
// When a license is selected, select the associated radio button.
$licenseTypes.filter( '[value="available"]' ).attr( 'checked', true );
if ( ! isNetworkActivation || $modal.hasClass( 'is-single-site-activation' ) ) {
enableActivateLicenseButton();
return true;
}
toggleActivationOnAllSites();
})
}
if ( hasLicenseTypes ) {
$licenseTypes.change(function() {
var
licenseKey = $modal.find( 'input.fs-license-key' ).val().trim(),
otherLicenseKeySelected = isOtherLicenseKeySelected();
if ( ( licenseKey.length > 0 || ( hasLicenseTypes && ! otherLicenseKeySelected ) ) &&
( $modal.hasClass( 'is-single-site-activation' ) || ! isNetworkActivation || hasSelectedSite() )
) {
/**
* If the "other" license is not empty or an available license is selected, enable the activate
* button.
*
* @author Leo Fajardo (@leorw)
*/
enableActivateLicenseButton();
} else {
disableActivateLicenseButton();
}
if ( '' !== licenseKey ) {
fetchLicenseUserData();
}
if ( ! isNetworkActivation ) {
return;
}
if ( otherLicenseKeySelected ) {
$applyOnAllSites.attr( 'disabled', false );
enableDisableSitesSelection();
resetActivateLicenseCheckboxLabel();
} else if ( ! $modal.hasClass( 'is-single-site-activation' ) ) {
toggleActivationOnAllSites();
}
});
if ( ! hasLicensesDropdown ) {
$availableLicenseKey.click(function() {
$licenseTypes.filter( '[value="available"]' ).click();
});
}
$otherLicenseKeyContainer.click(function() {
$licenseTypes.filter( '[value="other"]' ).click();
});
}
$body.on( 'click', 'span.activate-license.<?php echo $unique_affix ?> a, .activate-license-trigger.<?php echo $unique_affix ?>', function (evt) {
evt.preventDefault();
showModal( evt );
});
var licenseTimeout = null;
/**
* Disable activation button when license key is empty.
*
* @author Leo Fajardo (@leorw)
* @since 2.3.2
*/
$modal.on( 'keyup paste delete cut', 'input.fs-license-key', function () {
clearTimeout(licenseTimeout);
licenseTimeout = setTimeout( function () {
var licenseKey = $licenseKeyInput.val().trim();
if ( licenseKey == previousLicenseKey ) {
afterLicenseUserDataLoaded();
return;
}
if ( '' === licenseKey ) {
disableActivateLicenseButton();
$ownershipChangeOptionContainer.hide();
} else {
enableActivateLicenseButton();
if ( 32 <= licenseKey.length ) {
fetchLicenseUserData();
} else {
$ownershipChangeOptionContainer.hide();
}
}
previousLicenseKey = licenseKey;
}, 200 );
} ).focus();
$modal.on('input propertychange', 'input.fs-license-key', function () {
var licenseKey = $(this).val().trim();
/**
* If license key is not empty, enable the license activation button.
*/
if ( licenseKey.length > 0 && ( $modal.hasClass( 'is-single-site-activation' ) || ! isNetworkActivation || hasSelectedSite() ) ) {
enableActivateLicenseButton();
}
});
$modal.on( 'blur', 'input.fs-license-key', function( evt ) {
var
licenseKey = $(this).val().trim(),
$focusedElement = $( evt.relatedTarget ),
hasSelectedAvailableLicense = ( hasLicenseTypes && $focusedElement.parents( '.fs-available-license-key-container' ).length > 0 );
/**
* If license key is empty, disable the license activation button.
*/
if ( ( 0 === licenseKey.length && ( ! hasLicenseTypes || ! hasSelectedAvailableLicense ) ) ||
( isNetworkActivation && ! hasSelectedSite() )
) {
disableActivateLicenseButton();
}
});
$modal.on('click', '.button-activate-license', function (evt) {
evt.preventDefault();
if ($(this).hasClass('disabled')) {
return;
}
var
licenseKey = '';
if ( hasLicenseTypes ) {
if ( isOtherLicenseKeySelected() ) {
licenseKey = $otherLicenseKey.val();
} else {
if ( ! hasLicensesDropdown ) {
licenseKey = $availableLicenseKey.data( 'license-key' );
} else {
licenseKey = $licensesDropdown.val();
}
}
} else {
licenseKey = $licenseKeyInput.val().trim();
}
disableActivateLicenseButton();
if (0 === licenseKey.length) {
return;
}
var data = {
action : '<?php echo $fs->get_ajax_action( 'activate_license' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'activate_license' ) ?>',
license_key: licenseKey,
module_id : '<?php echo $fs->get_id() ?>'
};
if ( isNetworkActivation ) {
var
sites = [];
if ( null === singleBlogID ) {
var
applyOnAllSites = $applyOnAllSites.is( ':checked' );
$sitesListContainer.find( 'tr' ).each(function() {
var
$this = $( this ),
includeSite = ( applyOnAllSites || $this.find( 'input' ).is( ':checked' ) );
if ( ! includeSite )
return;
var site = {
uid : $this.find( '.uid' ).val(),
url : $this.find( '.url' ).val(),
title : $this.find( '.title' ).val(),
language: $this.find( '.language' ).val(),
charset : $this.find( '.charset' ).val(),
blog_id : $this.find( '.blog-id' ).find( 'span' ).text()
};
sites.push( site );
});
} else {
data.blog_id = singleBlogID;
}
data.sites = sites;
}
if ( $ownershipChangeOptionContainer.find( 'input:checked' ).length > 0 ) {
data.user_id = otherLicenseOwnerID;
}
$.ajax({
url: ajaxurl,
method: 'POST',
data: data,
beforeSend: function () {
$activateLicenseButton.text( '<?php fs_esc_js_echo_inline( 'Activating license', 'activating-license', $slug ) ?>...' );
},
success: function( result ) {
var resultObj = $.parseJSON( result );
if ( resultObj.success ) {
closeModal();
// Redirect to the "Account" page and sync the license.
window.location.href = resultObj.next_page;
} else {
showError( resultObj.error.message ? resultObj.error.message : resultObj.error );
resetActivateLicenseButton();
}
}
});
});
// If the user has clicked outside the window, close the modal.
$modal.on('click', '.fs-close, .button-secondary', function () {
closeModal();
return false;
});
}
registerEventHandlers();
$body.trigger('licenseActivationLoaded');
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*/
function enableDisableSitesSelection() {
var
canApplyOnAllSites = $applyOnAllSites.is( ':enabled' ),
disableSitesSelection = null;
if ( ! canApplyOnAllSites ) {
var
selectedSites = $sitesListContainer.find( 'input[type="checkbox"]:checked' ).length,
activationsLeft = Math.max( 0, $activationsLeft.data( 'left' ) - selectedSites );
disableSitesSelection = ( 0 === activationsLeft );
$activationsLeft.text( activationsLeft );
} else {
disableSitesSelection = false;
}
$sitesListContainer
.find( 'input[type="checkbox"]:not(:checked)' )
.attr( 'disabled', disableSitesSelection );
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*
* @returns {Boolean}
*/
function isOtherLicenseKeySelected() {
return ( hasLicenseTypes && 'other' === $licenseTypes.filter( ':checked' ).val() );
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*
* @returns {Boolean}
*/
function hasValidLicenseKey() {
var licenseKey = '';
if ( hasLicenseTypes ) {
if ( 'available' === $licenseTypes.filter( ':checked' ).val() ) {
return true;
} else {
licenseKey = $otherLicenseKey.val();
}
} else {
licenseKey = $modal.find( 'input.fs-license-key' ).val();
}
return ( licenseKey.trim().length > 0 );
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*
* @returns {Boolean}
*/
function hasSelectedSite() {
return ( $applyOnAllSites.is( ':checked' ) ||
$sitesListContainer.find( 'input[type="checkbox"]:checked:not(:disabled)' ).length > 0 );
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*/
function toggleActivationOnAllSites() {
var activationsLeft,
licenseID;
if (hasLicensesDropdown) {
var $selectedOption = $licensesDropdown.find( ':selected' );
activationsLeft = $selectedOption.data('left');
licenseID = $selectedOption.data('id');
} else {
activationsLeft = $availableLicenseKey.data('left');
licenseID = $availableLicenseKey.data('id');
}
// Cleanup previously auto-selected site.
$modal.find( '.fs-sites-list-container input[type=checkbox]:disabled' )
.attr('disabled', false)
.attr('checked', false);
var $blogsWithActiveLicense = $modal.find( '.fs-sites-list-container tr[data-license-id=' + licenseID + '] input[type=checkbox]' );
if ($blogsWithActiveLicense.length > 0) {
$blogsWithActiveLicense.attr('checked', true)
.attr('disabled', true);
activationsLeft += $blogsWithActiveLicense.length;
}
if ( activationsLeft >= totalSites ) {
$applyOnAllSites.attr( 'disabled', false );
enableDisableSitesSelection();
resetActivateLicenseCheckboxLabel();
return;
}
$applyOnAllSites.attr( 'checked', false );
$applyOnAllSites.attr( 'disabled', true );
showSites( true );
var
activateLicenseCheckboxLabel = '<?php fs_esc_js_echo_inline( 'Choose up to %s site(s) to activate the license on.', 'choose-up-to-n-sites-to-activate-the-license-on', $slug ) ?>';
activateLicenseCheckboxLabel = activateLicenseCheckboxLabel.replace( '%s', '<span data-left="' + activationsLeft + '" class="activations-left">' + activationsLeft + '</span>' );
// Update the label of the "Activate license on all sites" checkbox.
$applyOnAllSites.parent().find( 'span' ).html( activateLicenseCheckboxLabel );
$activationsLeft = $modal.find( '.activations-left' );
if ( hasSelectedSite() ) {
enableActivateLicenseButton();
enableDisableSitesSelection();
} else {
disableActivateLicenseButton();
}
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*/
function resetActivateLicenseCheckboxLabel() {
var activateLicenseCheckboxLabel = '<?php fs_esc_js_echo_inline( 'Activate license on all sites in the network.', 'activate-license-on-all-sites-in-the-network', $slug ) ?>';
$applyOnAllSites.parent().find( 'span' ).text( activateLicenseCheckboxLabel );
}
/**
* @author Leo Fajardo (@leorw)
* @since 2.0.0
*
* @param {Boolean} show
*/
function showSites( show ) {
$sitesListContainer.toggle( show );
if ( show && null === maxSitesListHeight ) {
/**
* Set the visible number of rows to 5 (5 * height of the first row).
*
* @author Leo Fajardo (@leorw)
*/
maxSitesListHeight = ( 5 * $sitesListContainer.find( 'tr:first' ).height() );
$sitesListContainer.css( 'max-height', maxSitesListHeight );
}
}
function showModal( evt ) {
resetModal();
// Display the dialog box.
$modal.addClass('active');
$body.addClass('has-fs-modal');
var
$singleInstallDetails = $( evt.target ).parents( 'tr.fs-install-details' ),
isSingleSiteActivation = ( $singleInstallDetails.length > 0 );
$modal.toggleClass( 'is-single-site-activation', isSingleSiteActivation );
singleBlogID = isSingleSiteActivation ?
$singleInstallDetails.prev().data( 'blog-id' ) :
null;
<?php if ( $fs->apply_filters( 'enable_per_site_activation', true ) ) : ?>
$multisiteOptionsContainer.toggle( isNetworkActivation && ! isSingleSiteActivation );
<?php endif ?>
if ( hasLicenseTypes ) {
$licenseTypes.attr( 'checked', false );
if ( hasLicensesDropdown ) {
$licensesDropdown.find( 'option:first' ).attr( 'selected', true ).trigger( 'change' );
} else {
$licenseTypes.filter( '[value="available"]' ).click();
}
$otherLicenseKey.val( '' );
} else {
$licenseKeyInput.val( '' );
$licenseKeyInput.focus();
}
}
function closeModal() {
$modal.removeClass('active');
$body.removeClass('has-fs-modal');
}
function resetActivateLicenseButton() {
enableActivateLicenseButton();
$activateLicenseButton.text( <?php echo json_encode( $activate_button_text ) ?> );
}
function resetModal() {
hideError();
resetActivateLicenseButton();
}
function enableActivateLicenseButton() {
$activateLicenseButton.removeClass( 'disabled' );
}
function disableActivateLicenseButton() {
$activateLicenseButton.addClass( 'disabled' );
}
function hideError() {
$licenseActivationMessage.hide();
}
function showError( msg ) {
$licenseActivationMessage.find( ' > p' ).html( msg );
$licenseActivationMessage.show();
}
});
})( jQuery );
</script>

View File

@ -0,0 +1,336 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.1.5
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$action = $fs->is_tracking_allowed() ?
'stop_tracking' :
'allow_tracking';
$reconnect_url = $fs->get_activation_url( array(
'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ),
'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ),
) );
$plugin_title = "<strong>{$fs->get_plugin()->title}</strong>";
$opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug );
$opt_in_text = fs_text_x_inline( 'Opt In', 'verb', 'opt-in', $slug );
if ( $fs->is_premium() ) {
$opt_in_message_appreciation = fs_text_inline( 'Connectivity to the licensing engine was successfully re-established. Automatic security & feature updates are now available through the WP Admin Dashboard.', 'premium-opt-in-message-appreciation', $slug );
$opt_out_message_subtitle = sprintf( fs_text_inline( 'Warning: Opting out will block automatic updates', 'premium-opt-out-message-appreciation', $slug ), $fs->get_module_type() );
$opt_out_message_usage_tracking = sprintf( fs_text_inline( 'Ongoing connectivity with the licensing engine is essential for receiving automatic security & feature updates of the paid product. To receive these updates, data like your license key, %1$s version, and WordPress version, is periodically sent to the server to check for updates. By opting out, you understand that your site won\'t receive automatic updates for %2$s from within the WP Admin Dashboard. This can put your site at risk, and we highly recommend to keep this connection active. If you do choose to opt-out, you\'ll need to check for %1$s updates and install them manually.', 'premium-opt-out-message-usage-tracking', $slug ), $fs->get_module_type(), $plugin_title );
$primary_cta_label = fs_text_inline( 'I\'d like to keep automatic updates', 'premium-opt-out-cancel', $slug );
} else {
$opt_in_message_appreciation = sprintf( fs_text_inline( 'We appreciate your help in making the %s better by letting us track some usage data.', 'opt-in-message-appreciation', $slug ), $fs->get_module_type() );
$opt_out_message_subtitle = $opt_in_message_appreciation;
$opt_out_message_usage_tracking = sprintf( fs_text_inline( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking.", 'opt-out-message-usage-tracking', $slug ), $plugin_title );
$primary_cta_label = fs_text_inline( 'On second thought - I want to continue helping', 'opt-out-cancel', $slug );
}
$opt_out_message_clicking_opt_out = sprintf(
fs_text_inline( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.', 'opt-out-message-clicking-opt-out', $slug ),
$plugin_title,
sprintf(
'<a href="%s" target="_blank" rel="noopener">%s</a>',
'https://freemius.com',
'freemius.com'
)
);
$admin_notice_params = array(
'id' => '',
'slug' => $fs->get_id(),
'type' => 'success',
'sticky' => false,
'plugin' => $fs->get_plugin()->title,
'message' => $opt_in_message_appreciation
);
$admin_notice_html = fs_get_template( 'admin-notice.php', $admin_notice_params );
$modal_content_html = "
<h2" . ( $fs->is_premium() ? ' style="color: red"' : '' ) . ">{$opt_out_message_subtitle}</h2>
<div class=\"notice notice-error inline opt-out-error-message\"><p></p></div>
<p>{$opt_out_message_usage_tracking}</p>
<p>{$opt_out_message_clicking_opt_out}</p>
<label class=\"fs-permission-extensions\"><div class=\"fs-switch fs-small fs-round fs-" . ( $fs->is_extensions_tracking_allowed() ? 'on' : 'off' ) . "\"><div class=\"fs-toggle\"></div></div> " . fs_text_inline( 'Plugins & themes tracking' ) . " <span class=\"fs-switch-feedback success\"></span></label>";
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
?>
<script type="text/javascript">
(function( $ ) {
$( document ).ready(function() {
var modalContentHtml = <?php echo json_encode( $modal_content_html ) ?>,
modalHtml =
'<div class="fs-modal fs-modal-opt-out">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_js( $opt_out_text ) ?></h4>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
+ ' </div>'
+ ' <div class="fs-modal-footer">'
+ ' <button class="button <?php echo $fs->is_premium() ? 'button-primary warn' : 'button-secondary' ?> button-opt-out" tabindex="1"><?php echo esc_js( $opt_out_text ) ?></button>'
+ ' <button class="button <?php echo $fs->is_premium() ? 'button-secondary' : 'button-primary' ?> button-close" tabindex="2"><?php echo esc_js( $primary_cta_label ) ?></button>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $(modalHtml),
$adminNotice = $( <?php echo json_encode( $admin_notice_html ) ?> ),
action = '<?php echo $action ?>',
actionLinkSelector = 'span.opt-in-or-opt-out.<?php echo $slug ?> a',
$optOutButton = $modal.find( '.button-opt-out' ),
$optOutErrorMessage = $modal.find( '.opt-out-error-message' ),
$extensionsTracking = $modal.find( '.fs-permission-extensions' ),
$body = $( 'body' ),
moduleID = '<?php echo $fs->get_id() ?>';
$modal.data( 'action', action );
$modal.appendTo( $body );
function registerActionLinkClick() {
$body.on( 'click', actionLinkSelector, function( evt ) {
evt.preventDefault();
if ( 'stop_tracking' == $modal.data( 'action' ) ) {
showModal();
} else {
optIn();
}
return false;
});
}
function registerEventHandlers() {
registerActionLinkClick();
$modal.on( 'click', '.button-opt-out', function( evt ) {
evt.preventDefault();
if ( $( this ).hasClass( 'disabled' ) ) {
return;
}
disableOptOutButton();
optOut();
});
// If the user has clicked outside the window, close the modal.
$modal.on( 'click', '.fs-close, .button-close', function() {
closeModal();
return false;
});
}
<?php if ( $fs->is_registered() ) : ?>
registerEventHandlers();
<?php endif ?>
function showModal() {
resetModal();
// Display the dialog box.
$modal.addClass( 'active' );
$body.addClass( 'has-fs-modal' );
}
function closeModal() {
$modal.removeClass( 'active' );
$body.removeClass( 'has-fs-modal' );
}
function resetOptOutButton() {
enableOptOutButton();
$optOutButton.text( <?php echo json_encode( $opt_out_text ) ?> );
}
function resetModal() {
hideError();
resetOptOutButton();
}
function optIn() {
sendRequest();
}
function optOut() {
sendRequest();
}
function sendRequest() {
var $actionLink = $( actionLinkSelector );
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action : ( 'stop_tracking' == action ?
'<?php echo $fs->get_ajax_action( 'stop_tracking' ) ?>' :
'<?php echo $fs->get_ajax_action( 'allow_tracking' ) ?>'
),
security : ( 'stop_tracking' == action ?
'<?php echo $fs->get_ajax_security( 'stop_tracking' ) ?>' :
'<?php echo $fs->get_ajax_security( 'allow_tracking' ) ?>'
),
module_id: moduleID,
_wp_http_referer: '<?php echo $fs->current_page_url() ?>'
},
beforeSend: function() {
if ( 'allow_tracking' == action ) {
$actionLink.text( '<?php fs_esc_js_echo_inline( 'Opting in', 'opting-in', $slug ) ?>...' );
} else {
$optOutButton.text( '<?php fs_esc_js_echo_inline( 'Opting out', 'opting-out', $slug ) ?>...' );
}
},
success: function( resultObj ) {
if ( resultObj.success ) {
if ( 'allow_tracking' == action ) {
action = 'stop_tracking';
$actionLink.text( '<?php echo esc_js( $opt_out_text ) ?>' );
showOptInAppreciationMessageAndScrollToTop();
} else {
action = 'allow_tracking';
$actionLink.text( '<?php echo esc_js( $opt_in_text ) ?>' );
closeModal();
if ( $adminNotice.length > 0 ) {
$adminNotice.remove();
}
}
$modal.data( 'action', action );
} else {
showError( resultObj.error );
resetOptOutButton();
}
}
});
}
var isUpdatingPermission = false;
$extensionsTracking.on('click', function() {
if (isUpdatingPermission) {
return false;
}
isUpdatingPermission = true;
var $switch = $extensionsTracking.find( '.fs-switch' ),
$switchFeedback = $extensionsTracking.find( '.fs-switch-feedback' );
$switch
.toggleClass( 'fs-on' )
.toggleClass( 'fs-off' );
$switchFeedback.html( '<i class="fs-ajax-spinner"></i>' );
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action : '<?php echo $fs->get_ajax_action( 'update_tracking_permission' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'update_tracking_permission' ) ?>',
module_id : moduleID,
_wp_http_referer: '<?php echo $fs->current_page_url() ?>',
permission: 'extensions',
is_enabled: $switch.hasClass('fs-on')
},
success: function( resultObj ) {
if ( resultObj.success ) {
$switchFeedback.html( '<i class="dashicons dashicons-yes"></i> <?php echo esc_js( fs_text_inline( 'Saved', 'saved', $slug ) ) ?>' )
} else {
$switch
.toggleClass( 'fs-on' )
.toggleClass( 'fs-off' );
}
isUpdatingPermission = false;
}
});
});
function enableOptOutButton() {
$optOutButton.removeClass( 'disabled' );
}
function disableOptOutButton() {
$optOutButton.addClass( 'disabled' );
}
function hideError() {
$optOutErrorMessage.hide();
}
function showOptInAppreciationMessageAndScrollToTop() {
$adminNotice.insertAfter( $( '#wpbody-content' ).find( ' > .wrap > h1' ) );
window.scrollTo(0, 0);
}
function showError( msg ) {
$optOutErrorMessage.find( ' > p' ).html( msg );
$optOutErrorMessage.show();
}
<?php if ( $fs->is_theme() ) : ?>
/**
* Add opt-in/out button to the active theme's buttons collection
* in the theme's extended details overlay.
*
* @author Vova Feldman (@svovaf)
* @since 1.2.2.7
*/
$('.theme-overlay').contentChange(function () {
if (0 === $('.theme-overlay.active').length) {
// Add opt-in/out button only to the currently active theme.
return;
}
if ($('#fs_theme_opt_in_out').length > 0){
// Button already there.
return;
}
var label = (('stop_tracking' == action) ?
'<?php echo esc_js( $opt_out_text ) ?>' :
'<?php echo esc_js( $opt_in_text ) ?>'),
href = (('stop_tracking' != action) ?
'<?php echo ( $fs->is_registered() ? '' : esc_js( $reconnect_url ) ) ?>' :
'');
var $actionLink = $('<a id="fs_theme_opt_in_out" href="' + encodeURI(href) + '" class="button">' + label + '</a>');
actionLinkSelector = '#fs_theme_opt_in_out';
$modal.data( 'action', action );
$('.theme-wrap .theme-actions .active-theme').append($actionLink);
if ('' === href) {
registerActionLinkClick();
}
});
<?php endif ?>
});
})( jQuery );
</script>

View File

@ -0,0 +1,205 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 2.0.2
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$plugin_data = $fs->get_plugin_data();
$plugin_name = $plugin_data['Name'];
$plugin_basename = $fs->get_plugin_basename();
$license = $fs->_get_license();
if ( ! is_object( $license ) ) {
$purchase_url = $fs->pricing_url();
} else {
$subscription = $fs->_get_subscription( $license->id );
$purchase_url = $fs->checkout_url(
is_object( $subscription ) ?
( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) :
WP_FS__PERIOD_LIFETIME,
false,
array( 'licenses' => $license->quota )
);
}
$message = sprintf(
fs_text_inline( 'There is a new version of %s available.', 'new-version-available-message', $slug ) .
fs_text_inline( ' %s to access version %s security & feature updates, and support.', 'x-for-updates-and-support', $slug ),
'<span id="plugin_name"></span>',
sprintf(
'<a id="pricing_url" href="">%s</a>',
is_object( $license ) ?
fs_text_inline( 'Renew your license now', 'renew-license-now', $slug ) :
fs_text_inline( 'Buy a license now', 'buy-license-now', $slug )
),
'<span id="new_version"></span>'
);
$modal_content_html = "<p>{$message}</p>";
$header_title = fs_text_inline( 'New Version Available', 'new-version-available', $slug );
$renew_license_button_text = is_object( $license ) ?
fs_text_inline( 'Renew license', 'renew-license', $slug ) :
fs_text_inline( 'Buy license', 'buy-license', $slug );
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
?>
<script type="text/javascript">
(function( $ ) {
$( document ).ready(function() {
if ( 0 === $( '.license-expired' ).length ) {
return;
}
var modalContentHtml = <?php echo json_encode( $modal_content_html ) ?>,
modalHtml =
'<div class="fs-modal fs-modal-upgrade-premium-version">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_js( $header_title ) ?></h4>'
+ ' <a href="!#" class="fs-close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'close a window', 'dismiss', $slug ) ) ?>"></i></a>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</div>'
+ ' </div>'
+ ' <div class="fs-modal-footer">'
+ ' <a class="button button-primary button-renew-license" tabindex="3" href="<?php echo $purchase_url ?>"><?php echo esc_js( $renew_license_button_text ) ?></a>'
+ ' <button class="button button-secondary button-close" tabindex="4"><?php fs_esc_js_echo_inline( 'Cancel', 'cancel', $slug ) ?></button>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $( modalHtml ),
isPluginsPage = <?php echo Freemius::is_plugins_page() ? 'true' : 'false' ?>;
$modal.appendTo( $( 'body' ) );
function registerEventHandlers() {
$( 'body' ).on( 'click', '.license-expired', function( evt ) {
var $this = $( this );
if ( ! $this.is( ':checked' ) ||
(
isPluginsPage &&
'update-selected' !== $( '#bulk-action-selector-top' ).val() &&
'update-selected' !== $( '#bulk-action-selector-bottom' ).val()
)
) {
return true;
}
evt.preventDefault();
evt.stopImmediatePropagation();
showModal( $this );
});
// If the user has clicked outside the window, close the modal.
$modal.on( 'click', '.fs-close, .button-secondary', function() {
closeModal();
return false;
});
if ( isPluginsPage ) {
$( 'body' ).on( 'change', 'select[id*="bulk-action-selector"]', function() {
if ( 'update-selected' === $( this ).val() ) {
setTimeout(function() {
$( '.license-expired' ).prop( 'checked', false );
$( '[id*="select-all"]' ).prop( 'checked', false );
}, 0);
}
});
}
$( 'body' ).on( 'click', '[id*="select-all"]', function( evt ) {
var $this = $( this );
if ( ! $this.is( ':checked' ) ) {
return true;
}
if ( isPluginsPage ) {
if ( 'update-selected' !== $( '#bulk-action-selector-top' ).val() &&
'update-selected' !== $( '#bulk-action-selector-bottom' ).val() ) {
return true;
}
}
var $table = $this.closest( 'table' ),
controlChecked = $this.prop( 'checked' ),
toggle = ( event.shiftKey || $this.data( 'wp-toggle' ) ),
$modules = $table.children( 'tbody' ).filter( ':visible' ).children().children( '.check-column' ).find( ':checkbox' ),
$modulesWithNonActiveLicense = $modules.filter( '.license-expired' );
if ( 0 === $modulesWithNonActiveLicense.length ) {
/**
* It's possible that the context HTML table element doesn't have checkboxes with
* ".license-expired" class if for example only the themes table has such checkboxes and the user
* clicks on a "Select All" checkbox on the plugins table which has no such checkboxes.
*
* @author Leo Fajardo (@leorw)
*/
return true;
} else if ( 1 === $modulesWithNonActiveLicense.length ) {
showModal( $modulesWithNonActiveLicense );
}
/**
* Prevent the default WordPress handler from checking all checkboxes.
*
* @author Leo Fajardo (@leorw)
*/
evt.stopImmediatePropagation();
$modules.filter( ':not(.license-expired)' )
.prop( 'checked', function() {
if ( $( this ).is( ':hidden,:disabled' ) ) {
return false;
}
if ( toggle ) {
return ! $( this ).prop( 'checked' );
} else if ( controlChecked ) {
return true;
}
return false;
});
return false;
});
}
registerEventHandlers();
function showModal( $module ) {
$modal.find( '#plugin_name' ).text( $module.data( 'plugin-name' ) );
$modal.find( '#pricing_url' ).attr( 'href', $module.data( 'pricing-url' ) );
$modal.find( '#new_version' ).text( $module.data( 'new-version' ) );
// Display the dialog box.
$modal.addClass( 'active' );
$( 'body' ).addClass( 'has-fs-modal' );
}
function closeModal() {
$modal.removeClass( 'active' );
$( 'body' ).removeClass( 'has-fs-modal' );
}
});
})( jQuery );
</script>

View File

@ -0,0 +1,47 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 2.0.2
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$license = $fs->_get_license();
if ( ! is_object( $license ) ) {
$purchase_url = $fs->pricing_url();
} else {
$subscription = $fs->_get_subscription( $license->id );
$purchase_url = $fs->checkout_url(
is_object( $subscription ) ?
( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) :
WP_FS__PERIOD_LIFETIME,
false,
array( 'licenses' => $license->quota )
);
}
$plugin_data = $fs->get_plugin_data();
?>
<script type="text/javascript">
(function( $ ) {
$( document ).ready(function() {
var $premiumVersionCheckbox = $( 'input[type="checkbox"][value="<?php echo $fs->get_plugin_basename() ?>"]' );
$premiumVersionCheckbox.addClass( 'license-expired' );
$premiumVersionCheckbox.data( 'plugin-name', <?php echo json_encode( $plugin_data['Name'] ) ?> );
$premiumVersionCheckbox.data( 'pricing-url', <?php echo json_encode( $purchase_url ) ?> );
$premiumVersionCheckbox.data( 'new-version', <?php echo json_encode( $VARS['new_version'] ) ?> );
});
})( jQuery );
</script>

View File

@ -0,0 +1,247 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$send_button_text = fs_text_inline( 'Send License Key', 'send-license-key', $slug );
$cancel_button_text = fs_text_inline( 'Cancel', 'cancel', $slug );
$email_address_placeholder = fs_esc_attr_inline( 'Email address', 'email-address', $slug );
$other_text = fs_text_inline( 'Other', 'other', $slug );
$is_freemium = $fs->is_freemium();
$send_button_text_html = esc_html($send_button_text);
$button_html = <<< HTML
<div class="button-container">
<a href="#" class="button button-primary button-send-license-key" tabindex="2">{$send_button_text_html}</a>
</div>
HTML;
if ( $is_freemium ) {
$current_user = Freemius::_get_current_wp_user();
$email = $current_user->user_email;
$esc_email = esc_attr( $email );
$form_html = <<< HTML
<div class="email-address-container">
<label><input name="email-address" type="radio" checked="checked" tabindex="1" value="{$esc_email}"> {$email}</label>
<label><input name="email-address" type="radio" tabindex="1" value="other">{$other_text}: <input class="email-address" type="text" placeholder="{$email_address_placeholder}"></label>
</div>
{$button_html}
HTML;
} else {
$email = '';
$form_html = <<< HTML
{$button_html}
<div class="email-address-container">
<input class="email-address" type="text" placeholder="{$email_address_placeholder}" tabindex="1">
</div>
HTML;
}
$message_above_input_field = fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug );
$modal_content_html = <<< HTML
<div class="notice notice-error inline license-resend-message"><p></p></div>
<p>{$message_above_input_field}</p>
<div class="input-container">
{$form_html}
</div>
HTML;
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
?>
<script type="text/javascript">
(function ($) {
$(document).ready(function () {
var contentHtml = <?php echo json_encode( $modal_content_html ); ?>,
modalHtml =
'<div class="fs-modal fs-modal-license-key-resend <?php echo $is_freemium ? 'fs-freemium' : 'fs-premium' ?>">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_js( $send_button_text ) ?></h4>'
+ ' <a href="#!" class="fs-close" tabindex="3" title="Close"><i class="dashicons dashicons-no" title="<?php echo esc_js( fs_text_x_inline( 'Dismiss', 'as close a window', 'dismiss', $slug ) ) ?>"></i></a>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + contentHtml + '</div>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $(modalHtml),
$sendButton = $modal.find('.button-send-license-key'),
$emailInput = $modal.find('input.email-address'),
$feedbackMessage = $modal.find('.license-resend-message'),
isFreemium = <?php echo json_encode( $is_freemium ) ?>,
userEmail = <?php echo json_encode( $email ) ?>,
moduleID = '<?php echo $fs->get_id() ?>',
isChild = false;
$modal.appendTo($('body'));
function registerEventHandlers() {
$('a.show-license-resend-modal-<?php echo $fs->get_unique_affix() ?>').click(function (evt) {
evt.preventDefault();
showModal();
});
if (isFreemium) {
$modal.on('change', 'input[type=radio][name=email-address]', function () {
updateButtonState();
});
$modal.on('focus', 'input.email-address', function () {
// Check custom email radio button on email input focus.
$($modal.find('input[type=radio]')[1]).prop('checked', true);
updateButtonState();
});
}
$modal.on('input propertychange', 'input.email-address', function () {
updateButtonState();
});
$modal.on('blur', 'input.email-address', function () {
updateButtonState();
});
$modal.on('click', '.fs-close', function (){
closeModal();
return false;
});
$modal.on('click', '.button', function (evt) {
evt.preventDefault();
if ($(this).hasClass('disabled')) {
return;
}
var email = getEmail();
disableButton();
if (!(-1 < email.indexOf('@'))) {
return;
}
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'resend_license_key' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'resend_license_key' ) ?>',
module_id : moduleID,
email : email
},
beforeSend: function () {
$sendButton.text('<?php fs_esc_js_echo_inline( 'Sending license key', 'sending-license-key', $slug ) ?>...');
},
success : function (result) {
var resultObj = $.parseJSON(result);
if (resultObj.success) {
closeModal();
} else {
showError(resultObj.error);
resetButton();
}
}
});
});
}
registerEventHandlers();
resetButton();
function showModal() {
resetModal();
// Display the dialog box.
$modal.addClass('active');
if (!isFreemium)
$emailInput.focus();
var $body = $('body');
isChild = $body.hasClass('has-fs-modal');
if (isChild) {
return;
}
$body.addClass('has-fs-modal');
}
function closeModal() {
$modal.removeClass('active');
// If child modal, do not remove the "has-fs-modal" class of the <body> element to keep its scrollbars hidden.
if (isChild) {
return;
}
$('body').removeClass('has-fs-modal');
}
function resetButton() {
updateButtonState();
$sendButton.text(<?php echo json_encode($send_button_text) ?>);
}
function resetModal() {
hideError();
resetButton();
$emailInput.val('');
}
function getEmail() {
var email = $emailInput.val().trim();
if (isFreemium) {
if ('other' != $modal.find('input[type=radio][name=email-address]:checked').val()) {
email = userEmail;
}
}
return email;
}
function updateButtonState() {
/**
* If email address is not empty, enable the send license key button.
*/
$sendButton.toggleClass('disabled', !( -1 < getEmail().indexOf('@') ));
}
function disableButton() {
$sendButton.addClass('disabled');
}
function hideError() {
$feedbackMessage.hide();
}
function showError(msg) {
$feedbackMessage.find(' > p').html(msg);
$feedbackMessage.show();
}
});
})(jQuery);
</script>

View File

@ -0,0 +1,277 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 2.2.1
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
/**
* @var FS_Plugin_License $license
*/
$license = $VARS['license'];
$has_trial = $VARS['has_trial'];
$subscription_cancellation_context = $has_trial ?
fs_text_inline( 'trial', 'trial', $slug ) :
fs_text_inline( 'subscription', 'subscription', $slug );
$plan = $fs->get_plan();
$module_label = $fs->get_module_label( true );
if ( $VARS['is_license_deactivation'] ) {
$subscription_cancellation_text = '';
} else {
$subscription_cancellation_text = sprintf(
fs_text_inline(
"Deactivating or uninstalling the %s will automatically disable the license, which you'll be able to use on another site.",
'deactivation-or-uninstall-message',
$slug
),
$module_label
) . ' ';
}
$subscription_cancellation_text .= sprintf(
fs_text_inline(
'In case you are NOT planning on using this %s on this site (or any other site) - would you like to cancel the %s as well?',
'cancel-subscription-message',
$slug
),
( $VARS['is_license_deactivation'] ? fs_text_inline( 'license', 'license', $slug ) : $module_label ),
$subscription_cancellation_context
);
$cancel_subscription_action_label = sprintf(
fs_esc_html_inline(
"Cancel %s - I no longer need any security & feature updates, nor support for %s because I'm not planning to use the %s on this, or any other site.",
'cancel-x',
$slug
),
esc_html( $subscription_cancellation_context ),
sprintf( '<strong>%s</strong>', esc_html( $fs->get_plugin_title() ) ),
esc_html( $module_label )
);
$keep_subscription_active_action_label = esc_html( sprintf(
fs_text_inline(
"Don't cancel %s - I'm still interested in getting security & feature updates, as well as be able to contact support.",
'dont-cancel-x',
$slug
),
$subscription_cancellation_context
) );
$subscription_cancellation_text = esc_html( $subscription_cancellation_text );
$subscription_cancellation_html = <<< HTML
<div class="notice notice-error inline"><p></p></div><p>{$subscription_cancellation_text}</p>
<ul class="subscription-actions">
<li>
<label>
<input type="radio" name="cancel-subscription" value="false"/>
<span>{$keep_subscription_active_action_label}</span>
</label>
</li>
<li>
<label>
<input type="radio" name="cancel-subscription" value="true"/>
<span>{$cancel_subscription_action_label}</span>
</label>
</li>
</ul>
HTML;
$downgrading_plan_text = fs_text_inline( 'Downgrading your plan', 'downgrading-plan', $slug );
$cancelling_subscription_text = fs_text_inline( 'Cancelling the subscription', 'cancelling-subscription', $slug );
/* translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription' */
$downgrade_x_confirm_text = fs_text_inline( '%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s.', 'downgrade-x-confirm', $slug );
$prices_increase_text = fs_text_inline( 'Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price.', 'pricing-increase-warning', $slug );
$after_downgrade_non_blocking_text = fs_text_inline( 'You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support.', 'after-downgrade-non-blocking', $slug );
$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 );
$after_downgrade_blocking_text_premium_only = fs_text_inline( 'Once your license expires you will no longer be able to use the %s, unless you activate it again with a valid premium license.', 'after-downgrade-blocking-premium-only', $slug );
$subscription_cancellation_confirmation_message = $has_trial ?
fs_text_inline( 'Cancelling the trial will immediately block access to all premium features. Are you sure?', 'cancel-trial-confirm', $slug ) :
sprintf(
'%s %s %s %s',
sprintf(
$downgrade_x_confirm_text,
($fs->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ),
$plan->title,
human_time_diff( time(), strtotime( $license->expiration ) )
),
(
$license->is_block_features ?
(
$fs->is_only_premium() ?
sprintf( $after_downgrade_blocking_text_premium_only, $module_label ) :
sprintf( $after_downgrade_blocking_text, $plan->title )
) :
sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs->get_module_label( true ) )
),
$prices_increase_text,
fs_esc_attr_inline( 'Are you sure you want to proceed?', 'proceed-confirmation', $slug )
);
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
?>
<script type="text/javascript">
(function( $ ) {
var modalHtml =
'<div class="fs-modal fs-modal-subscription-cancellation fs-modal-subscription-cancellation-<?php echo $fs->get_id() ?>">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_html( sprintf( fs_text_inline( 'Cancel %s?', 'cancel-x', $slug ), ucfirst( $subscription_cancellation_context ) ) ) ?></h4>'
+ ' </div>'
+ ' <div class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + <?php echo json_encode( $subscription_cancellation_html ) ?> + '<p class="fs-price-increase-warning" style="display: none;">' + <?php echo json_encode( $prices_increase_text ) ?> + '</p></div>'
+ ' </div>'
+ ' <div class="fs-modal-footer">'
+ ' <a href="#" class="button button-secondary button-close"><?php fs_esc_attr_echo( 'cancel', $slug ) ?></a>'
+ ' <a href="#" class="button button-primary button-deactivate disabled"><?php fs_esc_attr_echo_inline( 'Proceed', 'proceed', $slug ) ?></a>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $(modalHtml);
$modal.appendTo($('body'));
registerEventHandlers();
function registerEventHandlers() {
$modal.on( 'showModal', function() {
showModal();
});
$modal.on( 'closeModal', function() {
closeModal();
});
$modal.on('click', '.fs-modal-footer .button', function (evt) {
evt.preventDefault();
if ($(this).hasClass('disabled')) {
return;
}
var _this = $(this),
subscriptionCancellationActionEventName = <?php echo json_encode( $fs->get_action_tag( 'subscription_cancellation_action' ) ) ?>;
if ( _this.hasClass( 'button-primary' ) ) {
if ( 'true' !== $modal.find( 'input[name="cancel-subscription"]:checked' ).val() ) {
$modal.trigger( subscriptionCancellationActionEventName, false );
} else {
if ( confirm( <?php echo json_encode( $subscription_cancellation_confirmation_message ) ?> ) ) {
$modal.trigger( subscriptionCancellationActionEventName, true );
}
}
}
});
$modal.on('click', 'input[type="radio"]', function () {
var
$selectedOption = $( this ),
$primaryButton = $modal.find( '.button-primary' ),
isSelected = ( 'true' === $selectedOption.val() );
if ( isSelected ) {
$primaryButton.html( <?php echo json_encode( sprintf(
fs_text_inline( 'Cancel %s & Proceed', 'cancel-x-and-proceed', $slug ),
ucfirst( $subscription_cancellation_context )
) ) ?> );
$modal.find('.fs-price-increase-warning').show();
} else {
$primaryButton.html( <?php echo fs_json_encode_echo_inline( 'Proceed', 'proceed', $slug ) ?> );
$modal.find('.fs-price-increase-warning').hide();
}
$primaryButton.toggleClass( 'warn', isSelected );
$primaryButton.removeClass( 'disabled' );
});
// If the user has clicked outside the window, cancel it.
$modal.on('click', function (evt) {
var $target = $(evt.target);
// If the user has clicked anywhere in the modal dialog, just return.
if ($target.hasClass('fs-modal-body') || $target.hasClass('fs-modal-footer')) {
return;
}
// If the user has not clicked the close button and the clicked element is inside the modal dialog, just return.
if (
( ! $target.hasClass( 'button-close' ) ) &&
( $target.parents( '.fs-modal-body' ).length > 0 || $target.parents( '.fs-modal-footer' ).length > 0 )
) {
return;
}
closeModal();
return false;
});
}
function showModal() {
resetModal();
// Display the dialog box.
$modal.addClass('active');
$('body').addClass('has-fs-modal');
}
function closeModal() {
var activeModalsCount = $( '.fs-modal.active' ).length;
$modal.removeClass('active');
// If child modal, do not remove the "has-fs-modal" class of the <body> element to keep its scrollbars hidden.
if ( activeModalsCount > 1 ) {
return;
}
$('body').removeClass('has-fs-modal');
}
function resetModal() {
updateButtonLabels();
if ( 0 === $modal.find( '.subscription-actions' ).length ) {
$modal.find('.button-deactivate').removeClass('disabled');
} else {
$modal.find('.button-deactivate').addClass('disabled');
}
$modal.find('.fs-price-increase-warning').hide();
// Uncheck all radio buttons.
$modal.find('input[type="radio"]').prop('checked', false);
$modal.find('.message').hide();
}
function showMessage(message) {
$modal.find('.message').text(message).show();
}
function updateButtonLabels() {
$modal.find('.button-primary').text( <?php fs_json_encode_echo_inline( 'Proceed', 'proceed', $slug ) ?> );
$modal.find('.button-secondary').text( <?php fs_json_encode_echo( 'cancel', $slug ) ?> );
}
})( jQuery );
</script>

View File

@ -0,0 +1,181 @@
<?php
/**
* @package Freemius
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
* @since 1.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @var array $VARS
* @var Freemius $fs
*/
$fs = freemius( $VARS['id'] );
$slug = $fs->get_slug();
$message_header = sprintf(
/* translators: %1$s: Number of trial days; %2$s: Plan name; */
fs_text_inline( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.', 'start-trial-prompt-header', $slug ),
'<span class="var-trial_period"></span>',
'<span class="var-plan_title"></span>'
);
$message_content = sprintf(
/* translators: %s: Link to freemius.com */
fs_text_inline( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.', 'start-trial-prompt-message', $slug ),
$fs->get_module_type(),
sprintf(
'<a href="%s" target="_blank" rel="noopener">%s</a>',
'https://freemius.com',
'freemius.com'
)
);
$modal_content_html = <<< HTML
<div class="notice notice-error inline"><p></p></div>
<h3>{$message_header}</h3>
<p>{$message_content}</p>
HTML;
fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' );
?>
<script type="text/javascript">
(function ($) {
$(document).ready(function () {
var modalContentHtml = <?php echo json_encode( $modal_content_html ); ?>,
modalHtml =
'<div class="fs-modal fs-modal-license-key-resend">'
+ ' <div class="fs-modal-dialog">'
+ ' <div class="fs-modal-header">'
+ ' <h4><?php echo esc_js( fs_text_x_inline( 'Start free trial', 'call to action', 'start-free-trial', $slug ) ) ?></h4>'
+ ' </div>'
+ ' <div class="fs-modal-body">' + modalContentHtml + '</div>'
+ ' <div class="fs-modal-footer">'
+ ' <button class="button button-secondary button-close">' + <?php fs_json_encode_echo_inline( 'Cancel', 'cancel', $slug ) ?> +'</button>'
+ ' <button class="button button-primary button-connect">' + <?php fs_json_encode_echo_inline( 'Approve & Start Trial', 'approve-start-trial', $slug ) ?> +'</button>'
+ ' </div>'
+ ' </div>'
+ '</div>',
$modal = $( modalHtml ),
trialData;
$modal.appendTo($('body'));
var $errorNotice = $modal.find('.notice-error');
registerEventHandlers();
function registerEventHandlers() {
$modal.on('click', '.button-close', function () {
closeModal();
return false;
});
$modal.on('click', '.button-connect', function (evt) {
evt.preventDefault();
var $button = $(this);
$.ajax({
url : ajaxurl,
method : 'POST',
data : {
action : '<?php echo $fs->get_ajax_action( 'start_trial' ) ?>',
security : '<?php echo $fs->get_ajax_security( 'start_trial' ) ?>',
module_id: '<?php echo $fs->get_id() ?>',
trial : trialData
},
beforeSend: function () {
// Disable all buttons during trial activation.
$modal.find('.button').prop('disabled', true);
$button.text(<?php fs_json_encode_echo_inline( 'Starting trial', 'starting-trial', $slug ) ?> + '...');
setLoadingMode();
},
success : function (resultObj) {
if (resultObj.success) {
$button.text(<?php fs_json_encode_echo_inline( 'Please wait', 'please-wait', $slug ) ?> + '...');
// Redirect to the "Account" page and sync the license.
window.location.href = resultObj.data.next_page;
} else {
$button.text(<?php fs_json_encode_echo( 'approve-start-trial', $slug ) ?>);
resetLoadingMode();
showError(resultObj.error);
}
}
});
});
}
window.openTrialConfirmationModal = function showModal(data) {
resetModal();
// Display the dialog box.
$modal.addClass('active');
trialData = data;
var $modalBody = $modal.find('.fs-modal-body'),
$var;
for (var key in data) {
if (data.hasOwnProperty(key)) {
$var = $modalBody.find('.var-' + key);
if ($var.length > 0)
$var.html(data[key]);
}
}
$('body').addClass('has-fs-modal');
};
function closeModal() {
$modal.removeClass('active');
$('body').removeClass('has-fs-modal');
}
function resetModal() {
hideError();
}
function hideError() {
$errorNotice.hide();
}
function setLoadingMode() {
$modal.find('.button')
// Re-enable all buttons.
.prop('disabled', trialData)
// Stop loading cursor.
.css({'cursor': 'wait'});
// Stop loading cursor.
$(document.body).css({'cursor': 'wait'});
}
function resetLoadingMode() {
$modal.find('.button')
// Re-enable all buttons.
.prop('disabled', false)
// Stop loading cursor.
.css({'cursor': 'initial'});
// Stop loading cursor.
$(document.body).css({'cursor': 'initial'});
}
function showError(msg) {
$errorNotice.find(' > p').html(msg);
$errorNotice.show();
}
});
})(jQuery);
</script>