: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @copyright Copyright (c) 2015, Freemius, Inc.
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
if ( ! defined( 'ABSPATH' ) ) {
$fs = freemius( $VARS['id'] );
$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;
$message_below_input_field = sprintf(
fs_text_inline( 'The %1$s will be periodically sending essential license 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 ),
"<b>{$fs->get_plugin_title()}</b>"
$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_delegated_connection()
$network_activation_html = '';
$sites_details = array();
if ( $is_network_activation ) {
$all_sites = Freemius::get_sites();
$all_site_details = array();
$subsite_url_by_install_id = array();
$install_url_by_install_id = array();
foreach ( $all_sites as $site ) {
$site_details = $fs->get_site_info( $site );
if ( FS_Clone_Manager::instance()->is_temporary_duplicate_by_blog_id( $site_details['blog_id'] ) ) {
$blog_id = Freemius::get_site_blog_id( $site );
$install = $fs->get_install_by_blog_id($blog_id);
if ( is_object( $install ) ) {
if ( isset( $subsite_url_by_install_id[ $install->id ] ) ) {
$clone_subsite_url = $subsite_url_by_install_id[ $install->id ];
$clone_install_url = $install_url_by_install_id[ $install->id ];
* If we already have an install with the same URL as the subsite it's stored in, skip the current subsite. Otherwise, replace the existing install's data with the current subsite's install's data if the URLs match.
* @author Leo Fajardo (@leorw)
fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_url ) ) ||
fs_strip_url_protocol( untrailingslashit( $install->url ) ) !== fs_strip_url_protocol( untrailingslashit( $site_details['url'] ) )
if ( FS_Plugin_License::is_valid_id( $install->license_id ) ) {
$site_details['license_id'] = $install->license_id;
$subsite_url_by_install_id[ $install->id ] = $site_details['url'];
$install_url_by_install_id[ $install->id ] = $install->url;
$all_site_details[] = $site_details;
if ( $is_network_activation ) {
'sites' => $all_site_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 ) ) {
$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">
<tr class="fs-available-license-key-container">
<td><input type="radio" name="license_type" value="available"></td>
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 );
"%s-Site %s License - %s",
( $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>';
$available_licenses = array_values( $available_licenses );
* @var FS_Plugin_License $available_license
$available_license = $available_licenses[0];
"%s-Site %s License - %s",
( 1 == $available_license->quota ?
( $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
class="fs-available-license-key"
data-id="{$available_license->id}"
data-license-key="{$available_license->secret_key}"
data-left="{$available_license->left()}"
$license_input_html .= <<< HTML
<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>
<input id="other_license_key_{$unique_affix}" class="fs-license-key" type="text" placeholder="Enter license key" tabindex="1">
$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>";
* DO NOT ADD MAXLENGTH OR LIMIT THE LICENSE KEY LENGTH SINCE
* WE DO WANT TO ALLOW INPUT OF LONGER KEYS (E.G. WooCommerce Keys)
$modal_content_html = <<< HTML
<div class="notice notice-error inline license-activation-message"><p></p></div>
<p>{$message_above_input_field}</p>
<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}
* 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)
$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">
$( document ).ready(function() {
var modalContentHtml = <?php echo json_encode($modal_content_html); ?>,
'<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 class="fs-modal-body">'
+ ' <div class="fs-modal-panel active">' + modalContentHtml + '</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>'
$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' ),
$modal.appendTo( $body );
$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' ),
hasLicensesDropdown = ( $licensesDropdown.length > 0 ),
hasLicenseTypes = ( $licenseTypes.length > 0 ),
maxSitesListHeight = null,
totalSites = <?php echo count( $sites_details ) ?>,
previousLicenseKey = null,
otherLicenseOwnerID = null,
* @author Leo Fajardo (@leorw)
resetLoadingMode = function () {
$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)
setLoadingMode = function () {
$( document.body ).css( { 'cursor': 'wait' } );
* @author Leo Fajardo (@leorw)
afterLicenseUserDataLoaded = function () {
null !== otherLicenseOwnerID &&
otherLicenseOwnerID != <?php echo $fs->is_registered() ? $fs->get_user()->id : 'null' ?>
$ownershipChangeOptionContainer.show();
$ownershipChangeOptionContainer.hide();
$activateLicenseButton.focus();
* @author Leo Fajardo (@leorw)
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 );
if ( null !== otherLicenseOwnerID ) {
afterLicenseUserDataLoaded();
$activateLicenseButton.addClass( 'fs-loading' );
$activateLicenseButton.attr( 'disabled', 'disabled' );
$activateLicenseButton.html( '<?php fs_esc_js_echo_inline( 'Please wait', 'please-wait', $slug ) ?>...' );
url : <?php echo Freemius::ajax_url() ?>,
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' ) ?>',
module_id : '<?php echo $fs->get_id() ?>'
success: function ( result ) {
// Cache license owner's ID.
otherLicenseOwnerID = result.license_owner_id;
afterLicenseUserDataLoaded();
function registerEventHandlers() {
$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();
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();
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();
toggleActivationOnAllSites();
$licenseTypes.change(function() {
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
* @author Leo Fajardo (@leorw)
enableActivateLicenseButton();
disableActivateLicenseButton();
if ( '' !== licenseKey ) {
if ( ! isNetworkActivation ) {
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) {
var licenseTimeout = null;
* Disable activation button when license key is empty.
* @author Leo Fajardo (@leorw)